@actuate-media/cms-admin 0.8.0 → 0.8.1

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 (432) 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/components/Breadcrumbs.d.ts.map +1 -1
  10. package/dist/components/Breadcrumbs.js +2 -4
  11. package/dist/components/Breadcrumbs.js.map +1 -1
  12. package/dist/components/CommandPalette.d.ts.map +1 -1
  13. package/dist/components/CommandPalette.js +7 -3
  14. package/dist/components/CommandPalette.js.map +1 -1
  15. package/dist/components/ContentOverviewChart.d.ts.map +1 -1
  16. package/dist/components/ContentOverviewChart.js.map +1 -1
  17. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  18. package/dist/components/ErrorBoundary.js.map +1 -1
  19. package/dist/components/FocalPointPicker.d.ts.map +1 -1
  20. package/dist/components/FocalPointPicker.js +4 -2
  21. package/dist/components/FocalPointPicker.js.map +1 -1
  22. package/dist/components/FolderTree.d.ts.map +1 -1
  23. package/dist/components/FolderTree.js +18 -10
  24. package/dist/components/FolderTree.js.map +1 -1
  25. package/dist/components/LivePreview.d.ts +1 -1
  26. package/dist/components/LivePreview.d.ts.map +1 -1
  27. package/dist/components/LivePreview.js +6 -2
  28. package/dist/components/LivePreview.js.map +1 -1
  29. package/dist/components/LocaleProvider.d.ts.map +1 -1
  30. package/dist/components/LocaleProvider.js.map +1 -1
  31. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  32. package/dist/components/LocaleSwitcher.js +1 -1
  33. package/dist/components/LocaleSwitcher.js.map +1 -1
  34. package/dist/components/MediaPickerModal.d.ts.map +1 -1
  35. package/dist/components/MediaPickerModal.js.map +1 -1
  36. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  37. package/dist/components/PresenceIndicator.js +5 -2
  38. package/dist/components/PresenceIndicator.js.map +1 -1
  39. package/dist/components/SEOPanel.d.ts +1 -1
  40. package/dist/components/SEOPanel.d.ts.map +1 -1
  41. package/dist/components/SEOPanel.js +110 -24
  42. package/dist/components/SEOPanel.js.map +1 -1
  43. package/dist/components/SEOPerformance.d.ts.map +1 -1
  44. package/dist/components/SEOPerformance.js +2 -2
  45. package/dist/components/SEOPerformance.js.map +1 -1
  46. package/dist/components/ThemeProvider.d.ts.map +1 -1
  47. package/dist/components/ThemeProvider.js.map +1 -1
  48. package/dist/components/TipTapEditor.d.ts.map +1 -1
  49. package/dist/components/TipTapEditor.js +5 -1
  50. package/dist/components/TipTapEditor.js.map +1 -1
  51. package/dist/components/VersionHistory.d.ts +1 -1
  52. package/dist/components/VersionHistory.d.ts.map +1 -1
  53. package/dist/components/VersionHistory.js +1 -1
  54. package/dist/components/VersionHistory.js.map +1 -1
  55. package/dist/components/ui/Avatar.d.ts.map +1 -1
  56. package/dist/components/ui/Avatar.js.map +1 -1
  57. package/dist/components/ui/Badge.d.ts.map +1 -1
  58. package/dist/components/ui/Badge.js.map +1 -1
  59. package/dist/components/ui/Button.d.ts.map +1 -1
  60. package/dist/components/ui/Button.js.map +1 -1
  61. package/dist/components/ui/CommandPalette.d.ts.map +1 -1
  62. package/dist/components/ui/CommandPalette.js +8 -2
  63. package/dist/components/ui/CommandPalette.js.map +1 -1
  64. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -1
  65. package/dist/components/ui/ConfirmDialog.js.map +1 -1
  66. package/dist/components/ui/DataTable.d.ts.map +1 -1
  67. package/dist/components/ui/DataTable.js +1 -3
  68. package/dist/components/ui/DataTable.js.map +1 -1
  69. package/dist/components/ui/EmptyState.d.ts.map +1 -1
  70. package/dist/components/ui/EmptyState.js +1 -1
  71. package/dist/components/ui/EmptyState.js.map +1 -1
  72. package/dist/components/ui/Modal.d.ts.map +1 -1
  73. package/dist/components/ui/Modal.js.map +1 -1
  74. package/dist/components/ui/Pagination.d.ts +1 -1
  75. package/dist/components/ui/Pagination.d.ts.map +1 -1
  76. package/dist/components/ui/Pagination.js +7 -2
  77. package/dist/components/ui/Pagination.js.map +1 -1
  78. package/dist/components/ui/SearchInput.d.ts.map +1 -1
  79. package/dist/components/ui/SearchInput.js.map +1 -1
  80. package/dist/components/ui/Skeleton.d.ts.map +1 -1
  81. package/dist/components/ui/Skeleton.js.map +1 -1
  82. package/dist/components/ui/Toast.d.ts.map +1 -1
  83. package/dist/components/ui/Toast.js.map +1 -1
  84. package/dist/components/ui/index.d.ts.map +1 -1
  85. package/dist/components/ui/index.js.map +1 -1
  86. package/dist/fields/ArrayField.d.ts.map +1 -1
  87. package/dist/fields/ArrayField.js +1 -1
  88. package/dist/fields/ArrayField.js.map +1 -1
  89. package/dist/fields/BlockBuilderField.d.ts.map +1 -1
  90. package/dist/fields/BlockBuilderField.js +7 -7
  91. package/dist/fields/BlockBuilderField.js.map +1 -1
  92. package/dist/fields/DateField.d.ts.map +1 -1
  93. package/dist/fields/DateField.js +1 -1
  94. package/dist/fields/DateField.js.map +1 -1
  95. package/dist/fields/FieldRenderer.d.ts.map +1 -1
  96. package/dist/fields/FieldRenderer.js.map +1 -1
  97. package/dist/fields/GroupField.d.ts.map +1 -1
  98. package/dist/fields/GroupField.js +1 -1
  99. package/dist/fields/GroupField.js.map +1 -1
  100. package/dist/fields/MediaField.d.ts.map +1 -1
  101. package/dist/fields/MediaField.js +1 -1
  102. package/dist/fields/MediaField.js.map +1 -1
  103. package/dist/fields/NavBuilderField.d.ts.map +1 -1
  104. package/dist/fields/NavBuilderField.js +2 -5
  105. package/dist/fields/NavBuilderField.js.map +1 -1
  106. package/dist/fields/NumberField.d.ts +1 -1
  107. package/dist/fields/NumberField.d.ts.map +1 -1
  108. package/dist/fields/NumberField.js +2 -2
  109. package/dist/fields/NumberField.js.map +1 -1
  110. package/dist/fields/RelationshipField.d.ts.map +1 -1
  111. package/dist/fields/RelationshipField.js +7 -3
  112. package/dist/fields/RelationshipField.js.map +1 -1
  113. package/dist/fields/RichTextField.d.ts +1 -1
  114. package/dist/fields/RichTextField.d.ts.map +1 -1
  115. package/dist/fields/RichTextField.js +2 -2
  116. package/dist/fields/RichTextField.js.map +1 -1
  117. package/dist/fields/SelectField.d.ts.map +1 -1
  118. package/dist/fields/SelectField.js +9 -7
  119. package/dist/fields/SelectField.js.map +1 -1
  120. package/dist/fields/SlugField.d.ts.map +1 -1
  121. package/dist/fields/SlugField.js +1 -1
  122. package/dist/fields/SlugField.js.map +1 -1
  123. package/dist/fields/TextField.d.ts +1 -1
  124. package/dist/fields/TextField.d.ts.map +1 -1
  125. package/dist/fields/TextField.js +2 -2
  126. package/dist/fields/TextField.js.map +1 -1
  127. package/dist/fields/ToggleField.d.ts.map +1 -1
  128. package/dist/fields/ToggleField.js +1 -1
  129. package/dist/fields/ToggleField.js.map +1 -1
  130. package/dist/fields/block-types.d.ts.map +1 -1
  131. package/dist/fields/block-types.js +28 -8
  132. package/dist/fields/block-types.js.map +1 -1
  133. package/dist/fields/index.d.ts.map +1 -1
  134. package/dist/fields/index.js.map +1 -1
  135. package/dist/hooks/useBuilderState.d.ts.map +1 -1
  136. package/dist/hooks/useBuilderState.js.map +1 -1
  137. package/dist/hooks/useContentLock.d.ts.map +1 -1
  138. package/dist/hooks/useContentLock.js.map +1 -1
  139. package/dist/hooks/useDebounce.js.map +1 -1
  140. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  141. package/dist/hooks/useKeyboardShortcuts.js.map +1 -1
  142. package/dist/index.d.ts +2 -2
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js.map +1 -1
  145. package/dist/layout/Header.d.ts.map +1 -1
  146. package/dist/layout/Header.js.map +1 -1
  147. package/dist/layout/Layout.d.ts.map +1 -1
  148. package/dist/layout/Layout.js.map +1 -1
  149. package/dist/layout/Sidebar.d.ts +1 -1
  150. package/dist/layout/Sidebar.d.ts.map +1 -1
  151. package/dist/layout/Sidebar.js +5 -8
  152. package/dist/layout/Sidebar.js.map +1 -1
  153. package/dist/lib/api.js.map +1 -1
  154. package/dist/lib/search.d.ts.map +1 -1
  155. package/dist/lib/search.js +3 -5
  156. package/dist/lib/search.js.map +1 -1
  157. package/dist/lib/useApiData.d.ts.map +1 -1
  158. package/dist/lib/useApiData.js.map +1 -1
  159. package/dist/lib/utils.d.ts.map +1 -1
  160. package/dist/lib/utils.js.map +1 -1
  161. package/dist/router/index.d.ts.map +1 -1
  162. package/dist/router/index.js +1 -3
  163. package/dist/router/index.js.map +1 -1
  164. package/dist/views/CollectionList.d.ts.map +1 -1
  165. package/dist/views/CollectionList.js +56 -17
  166. package/dist/views/CollectionList.js.map +1 -1
  167. package/dist/views/Dashboard.d.ts.map +1 -1
  168. package/dist/views/Dashboard.js +26 -13
  169. package/dist/views/Dashboard.js.map +1 -1
  170. package/dist/views/DocumentEdit.d.ts +1 -1
  171. package/dist/views/DocumentEdit.d.ts.map +1 -1
  172. package/dist/views/DocumentEdit.js +33 -15
  173. package/dist/views/DocumentEdit.js.map +1 -1
  174. package/dist/views/ForgotPassword.d.ts.map +1 -1
  175. package/dist/views/ForgotPassword.js.map +1 -1
  176. package/dist/views/FormEditor.d.ts.map +1 -1
  177. package/dist/views/FormEditor.js +8 -2
  178. package/dist/views/FormEditor.js.map +1 -1
  179. package/dist/views/FormSubmissions.d.ts.map +1 -1
  180. package/dist/views/FormSubmissions.js +6 -6
  181. package/dist/views/FormSubmissions.js.map +1 -1
  182. package/dist/views/Forms.d.ts.map +1 -1
  183. package/dist/views/Forms.js.map +1 -1
  184. package/dist/views/Login.d.ts.map +1 -1
  185. package/dist/views/Login.js +5 -2
  186. package/dist/views/Login.js.map +1 -1
  187. package/dist/views/MediaBrowser.d.ts.map +1 -1
  188. package/dist/views/MediaBrowser.js +39 -19
  189. package/dist/views/MediaBrowser.js.map +1 -1
  190. package/dist/views/PageEditor.d.ts.map +1 -1
  191. package/dist/views/PageEditor.js.map +1 -1
  192. package/dist/views/Pages.d.ts.map +1 -1
  193. package/dist/views/Pages.js +20 -10
  194. package/dist/views/Pages.js.map +1 -1
  195. package/dist/views/PostEditor.d.ts.map +1 -1
  196. package/dist/views/PostEditor.js.map +1 -1
  197. package/dist/views/Posts.d.ts.map +1 -1
  198. package/dist/views/Posts.js +13 -7
  199. package/dist/views/Posts.js.map +1 -1
  200. package/dist/views/Redirects.d.ts.map +1 -1
  201. package/dist/views/Redirects.js +17 -5
  202. package/dist/views/Redirects.js.map +1 -1
  203. package/dist/views/ResetPassword.d.ts.map +1 -1
  204. package/dist/views/ResetPassword.js.map +1 -1
  205. package/dist/views/SEO.d.ts.map +1 -1
  206. package/dist/views/SEO.js +39 -16
  207. package/dist/views/SEO.js.map +1 -1
  208. package/dist/views/ScriptTagEditor.d.ts.map +1 -1
  209. package/dist/views/ScriptTagEditor.js +2 -1
  210. package/dist/views/ScriptTagEditor.js.map +1 -1
  211. package/dist/views/ScriptTags.d.ts.map +1 -1
  212. package/dist/views/ScriptTags.js.map +1 -1
  213. package/dist/views/Settings.d.ts.map +1 -1
  214. package/dist/views/Settings.js +38 -11
  215. package/dist/views/Settings.js.map +1 -1
  216. package/dist/views/SetupWizard.d.ts.map +1 -1
  217. package/dist/views/SetupWizard.js.map +1 -1
  218. package/dist/views/Users.d.ts.map +1 -1
  219. package/dist/views/Users.js +5 -3
  220. package/dist/views/Users.js.map +1 -1
  221. package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -1
  222. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  223. package/dist/views/page-builder/AIBlockAssist.js.map +1 -1
  224. package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -1
  225. package/dist/views/page-builder/AIGenerateDialog.js +4 -1
  226. package/dist/views/page-builder/AIGenerateDialog.js.map +1 -1
  227. package/dist/views/page-builder/BlockEditor.d.ts.map +1 -1
  228. package/dist/views/page-builder/BlockEditor.js +1 -1
  229. package/dist/views/page-builder/BlockEditor.js.map +1 -1
  230. package/dist/views/page-builder/BlockPicker.d.ts.map +1 -1
  231. package/dist/views/page-builder/BlockPicker.js.map +1 -1
  232. package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
  233. package/dist/views/page-builder/BottomBar.js.map +1 -1
  234. package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -1
  235. package/dist/views/page-builder/BuilderToolbar.js.map +1 -1
  236. package/dist/views/page-builder/ContextPanel.d.ts.map +1 -1
  237. package/dist/views/page-builder/ContextPanel.js +4 -1
  238. package/dist/views/page-builder/ContextPanel.js.map +1 -1
  239. package/dist/views/page-builder/DesignScore.d.ts.map +1 -1
  240. package/dist/views/page-builder/DesignScore.js.map +1 -1
  241. package/dist/views/page-builder/NodeSettings.d.ts.map +1 -1
  242. package/dist/views/page-builder/NodeSettings.js +1 -1
  243. package/dist/views/page-builder/NodeSettings.js.map +1 -1
  244. package/dist/views/page-builder/PageBuilder.d.ts +1 -1
  245. package/dist/views/page-builder/PageBuilder.d.ts.map +1 -1
  246. package/dist/views/page-builder/PageBuilder.js +4 -2
  247. package/dist/views/page-builder/PageBuilder.js.map +1 -1
  248. package/dist/views/page-builder/PageSettings.d.ts.map +1 -1
  249. package/dist/views/page-builder/PageSettings.js.map +1 -1
  250. package/dist/views/page-builder/PageTemplates.d.ts.map +1 -1
  251. package/dist/views/page-builder/PageTemplates.js.map +1 -1
  252. package/dist/views/page-builder/SEOPanel.d.ts.map +1 -1
  253. package/dist/views/page-builder/SEOPanel.js +1 -3
  254. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  255. package/dist/views/page-builder/SavedSections.d.ts.map +1 -1
  256. package/dist/views/page-builder/SavedSections.js +3 -7
  257. package/dist/views/page-builder/SavedSections.js.map +1 -1
  258. package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -1
  259. package/dist/views/page-builder/TemplatePicker.js.map +1 -1
  260. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -1
  261. package/dist/views/page-builder/block-renderers/CTAPreview.js +1 -1
  262. package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -1
  263. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -1
  264. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  265. package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -1
  266. package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -1
  267. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -5
  268. package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -1
  269. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -1
  270. package/dist/views/page-builder/block-renderers/FAQPreview.js +4 -1
  271. package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -1
  272. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -1
  273. package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -1
  274. package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -1
  275. package/dist/views/page-builder/block-renderers/FormPreview.js +2 -2
  276. package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -1
  277. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -1
  278. package/dist/views/page-builder/block-renderers/GalleryPreview.js +1 -3
  279. package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -1
  280. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -1
  281. package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -1
  282. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -1
  283. package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -1
  284. package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -1
  285. package/dist/views/page-builder/block-renderers/TextPreview.js +2 -6
  286. package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -1
  287. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -1
  288. package/dist/views/page-builder/block-renderers/VideoPreview.js +2 -5
  289. package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -1
  290. package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -1
  291. package/dist/views/page-builder/block-renderers/index.js.map +1 -1
  292. package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -1
  293. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -5
  294. package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -1
  295. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -1
  296. package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -1
  297. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -1
  298. package/dist/views/page-builder/canvas/ColumnRenderer.js +1 -5
  299. package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -1
  300. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -1
  301. package/dist/views/page-builder/canvas/ContainerRenderer.js +1 -5
  302. package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -1
  303. package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -1
  304. package/dist/views/page-builder/canvas/RowRenderer.js +1 -5
  305. package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -1
  306. package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -1
  307. package/dist/views/page-builder/canvas/SectionRenderer.js +1 -5
  308. package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -1
  309. package/dist/views/page-builder/canvas/index.d.ts.map +1 -1
  310. package/dist/views/page-builder/canvas/index.js.map +1 -1
  311. package/package.json +2 -2
  312. package/src/AdminRoot.tsx +263 -191
  313. package/src/__tests__/lib/search.test.ts +60 -69
  314. package/src/__tests__/lib/utils.test.ts +12 -12
  315. package/src/__tests__/router/match-route.test.ts +24 -26
  316. package/src/__tests__/router/strip-base.test.ts +15 -15
  317. package/src/components/Breadcrumbs.tsx +27 -24
  318. package/src/components/CommandPalette.tsx +115 -99
  319. package/src/components/ContentOverviewChart.tsx +19 -14
  320. package/src/components/ErrorBoundary.tsx +13 -13
  321. package/src/components/FocalPointPicker.tsx +31 -20
  322. package/src/components/FolderTree.tsx +172 -139
  323. package/src/components/LivePreview.tsx +68 -41
  324. package/src/components/LocaleProvider.tsx +26 -20
  325. package/src/components/LocaleSwitcher.tsx +9 -11
  326. package/src/components/MediaPickerModal.tsx +46 -45
  327. package/src/components/PresenceIndicator.tsx +30 -27
  328. package/src/components/SEOPanel.tsx +378 -228
  329. package/src/components/SEOPerformance.tsx +52 -30
  330. package/src/components/ThemeProvider.tsx +46 -46
  331. package/src/components/TipTapEditor.tsx +60 -64
  332. package/src/components/VersionHistory.tsx +63 -52
  333. package/src/components/ui/Avatar.tsx +8 -8
  334. package/src/components/ui/Badge.tsx +7 -5
  335. package/src/components/ui/Button.tsx +24 -13
  336. package/src/components/ui/CommandPalette.tsx +56 -42
  337. package/src/components/ui/ConfirmDialog.tsx +14 -14
  338. package/src/components/ui/DataTable.tsx +37 -39
  339. package/src/components/ui/EmptyState.tsx +9 -11
  340. package/src/components/ui/Modal.tsx +21 -15
  341. package/src/components/ui/Pagination.tsx +34 -19
  342. package/src/components/ui/SearchInput.tsx +17 -7
  343. package/src/components/ui/Skeleton.tsx +7 -7
  344. package/src/components/ui/Toast.tsx +29 -22
  345. package/src/components/ui/index.ts +24 -24
  346. package/src/fields/ArrayField.tsx +43 -25
  347. package/src/fields/BlockBuilderField.tsx +80 -99
  348. package/src/fields/DateField.tsx +20 -12
  349. package/src/fields/FieldRenderer.tsx +34 -34
  350. package/src/fields/GroupField.tsx +8 -10
  351. package/src/fields/MediaField.tsx +8 -10
  352. package/src/fields/NavBuilderField.tsx +24 -25
  353. package/src/fields/NumberField.tsx +21 -14
  354. package/src/fields/RelationshipField.tsx +105 -91
  355. package/src/fields/RichTextField.tsx +16 -12
  356. package/src/fields/SelectField.tsx +42 -34
  357. package/src/fields/SlugField.tsx +29 -17
  358. package/src/fields/TextField.tsx +24 -16
  359. package/src/fields/ToggleField.tsx +7 -9
  360. package/src/fields/block-types.ts +50 -24
  361. package/src/fields/index.ts +17 -17
  362. package/src/hooks/useBuilderState.ts +260 -221
  363. package/src/hooks/useContentLock.ts +23 -20
  364. package/src/hooks/useDebounce.ts +7 -7
  365. package/src/hooks/useKeyboardShortcuts.ts +16 -16
  366. package/src/index.ts +69 -58
  367. package/src/layout/Header.tsx +21 -20
  368. package/src/layout/Layout.tsx +22 -24
  369. package/src/layout/Sidebar.tsx +107 -72
  370. package/src/lib/api.ts +34 -34
  371. package/src/lib/search.ts +30 -34
  372. package/src/lib/useApiData.ts +65 -62
  373. package/src/lib/utils.ts +3 -3
  374. package/src/router/index.ts +33 -35
  375. package/src/styles/build-input.css +2 -2
  376. package/src/styles/tailwind.css +1 -1
  377. package/src/styles/theme.css +7 -1
  378. package/src/views/CollectionList.tsx +275 -121
  379. package/src/views/Dashboard.tsx +164 -117
  380. package/src/views/DocumentEdit.tsx +298 -253
  381. package/src/views/ForgotPassword.tsx +27 -23
  382. package/src/views/FormEditor.tsx +165 -99
  383. package/src/views/FormSubmissions.tsx +261 -117
  384. package/src/views/Forms.tsx +56 -26
  385. package/src/views/Login.tsx +107 -84
  386. package/src/views/MediaBrowser.tsx +717 -523
  387. package/src/views/PageEditor.tsx +44 -46
  388. package/src/views/Pages.tsx +312 -149
  389. package/src/views/PostEditor.tsx +57 -51
  390. package/src/views/Posts.tsx +206 -74
  391. package/src/views/Redirects.tsx +173 -117
  392. package/src/views/ResetPassword.tsx +43 -32
  393. package/src/views/SEO.tsx +589 -160
  394. package/src/views/ScriptTagEditor.tsx +69 -69
  395. package/src/views/ScriptTags.tsx +54 -42
  396. package/src/views/Settings.tsx +430 -220
  397. package/src/views/SetupWizard.tsx +69 -46
  398. package/src/views/Users.tsx +154 -120
  399. package/src/views/page-builder/AIBlockAssist.tsx +21 -25
  400. package/src/views/page-builder/AIGenerateDialog.tsx +134 -127
  401. package/src/views/page-builder/BlockEditor.tsx +94 -96
  402. package/src/views/page-builder/BlockPicker.tsx +73 -88
  403. package/src/views/page-builder/BottomBar.tsx +15 -11
  404. package/src/views/page-builder/BuilderToolbar.tsx +32 -29
  405. package/src/views/page-builder/ContextPanel.tsx +57 -57
  406. package/src/views/page-builder/DesignScore.tsx +52 -59
  407. package/src/views/page-builder/NodeSettings.tsx +59 -59
  408. package/src/views/page-builder/PageBuilder.tsx +156 -155
  409. package/src/views/page-builder/PageSettings.tsx +16 -15
  410. package/src/views/page-builder/PageTemplates.tsx +23 -17
  411. package/src/views/page-builder/SEOPanel.tsx +90 -111
  412. package/src/views/page-builder/SavedSections.tsx +99 -105
  413. package/src/views/page-builder/TemplatePicker.tsx +44 -48
  414. package/src/views/page-builder/block-renderers/CTAPreview.tsx +11 -13
  415. package/src/views/page-builder/block-renderers/CardsPreview.tsx +13 -15
  416. package/src/views/page-builder/block-renderers/CodePreview.tsx +16 -16
  417. package/src/views/page-builder/block-renderers/FAQPreview.tsx +20 -23
  418. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +5 -5
  419. package/src/views/page-builder/block-renderers/FormPreview.tsx +9 -13
  420. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +22 -28
  421. package/src/views/page-builder/block-renderers/HeroPreview.tsx +17 -30
  422. package/src/views/page-builder/block-renderers/ImagePreview.tsx +12 -12
  423. package/src/views/page-builder/block-renderers/TextPreview.tsx +22 -22
  424. package/src/views/page-builder/block-renderers/VideoPreview.tsx +13 -18
  425. package/src/views/page-builder/block-renderers/index.ts +17 -17
  426. package/src/views/page-builder/canvas/BlockRenderer.tsx +19 -23
  427. package/src/views/page-builder/canvas/BuilderCanvas.tsx +17 -20
  428. package/src/views/page-builder/canvas/ColumnRenderer.tsx +22 -26
  429. package/src/views/page-builder/canvas/ContainerRenderer.tsx +20 -24
  430. package/src/views/page-builder/canvas/RowRenderer.tsx +19 -23
  431. package/src/views/page-builder/canvas/SectionRenderer.tsx +30 -34
  432. package/src/views/page-builder/canvas/index.ts +2 -2
@@ -1,13 +1,13 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useCallback, useRef, useMemo } from 'react';
3
+ import { useState, useCallback, useRef, useMemo } from 'react'
4
4
  import type {
5
5
  PageNode,
6
6
  BuilderNode,
7
7
  BlockNode,
8
8
  SectionNode,
9
9
  ColumnNode,
10
- } from '@actuate-media/cms-core';
10
+ } from '@actuate-media/cms-core'
11
11
  import {
12
12
  addNode,
13
13
  removeNode,
@@ -23,272 +23,311 @@ import {
23
23
  createColumn,
24
24
  createBlock,
25
25
  hasChildren,
26
- } from '@actuate-media/cms-core';
26
+ } from '@actuate-media/cms-core'
27
27
 
28
- export type DeviceMode = 'desktop' | 'tablet' | 'mobile';
29
- export type PanelTab = 'block' | 'node' | 'page' | 'seo' | 'design';
28
+ export type DeviceMode = 'desktop' | 'tablet' | 'mobile'
29
+ export type PanelTab = 'block' | 'node' | 'page' | 'seo' | 'design'
30
30
 
31
31
  export interface PageSettings {
32
- title: string;
33
- slug: string;
34
- template?: string;
35
- metaTitle?: string;
36
- metaDescription?: string;
37
- ogImage?: string;
38
- focusKeyphrase?: string;
39
- schemaType?: string;
32
+ title: string
33
+ slug: string
34
+ template?: string
35
+ metaTitle?: string
36
+ metaDescription?: string
37
+ ogImage?: string
38
+ focusKeyphrase?: string
39
+ schemaType?: string
40
40
  }
41
41
 
42
42
  export interface BuilderState {
43
- tree: PageNode;
44
- selectedNodeId: string | null;
45
- selectedNode: BuilderNode | null;
46
- deviceMode: DeviceMode;
47
- activeTab: PanelTab;
48
- pageSettings: PageSettings;
49
- dirty: boolean;
50
- canUndo: boolean;
51
- canRedo: boolean;
52
- showGridOverlay: boolean;
43
+ tree: PageNode
44
+ selectedNodeId: string | null
45
+ selectedNode: BuilderNode | null
46
+ deviceMode: DeviceMode
47
+ activeTab: PanelTab
48
+ pageSettings: PageSettings
49
+ dirty: boolean
50
+ canUndo: boolean
51
+ canRedo: boolean
52
+ showGridOverlay: boolean
53
53
  }
54
54
 
55
55
  export interface BuilderActions {
56
- selectNode: (id: string | null) => void;
57
- setDeviceMode: (mode: DeviceMode) => void;
58
- setActiveTab: (tab: PanelTab) => void;
59
- setPageSettings: (settings: Partial<PageSettings>) => void;
60
- setShowGridOverlay: (show: boolean) => void;
61
-
62
- addSection: () => void;
63
- addRowToSection: (sectionId: string) => void;
64
- addBlockToColumn: (columnId: string, blockType: string, variant?: string) => void;
65
- addNodeAtId: (parentId: string, node: BuilderNode, index?: number) => void;
66
- removeNodeById: (id: string) => void;
67
- moveNodeById: (id: string, newParentId: string, index?: number) => void;
68
- updateSettings: (id: string, settings: Record<string, unknown>) => void;
69
- updateBlock: (id: string, data: Record<string, unknown>) => void;
70
- duplicateNode: (id: string) => void;
71
- moveNodeUp: (id: string) => void;
72
- moveNodeDown: (id: string) => void;
73
-
74
- undo: () => void;
75
- redo: () => void;
76
- markClean: () => void;
77
- replaceTree: (tree: PageNode) => void;
56
+ selectNode: (id: string | null) => void
57
+ setDeviceMode: (mode: DeviceMode) => void
58
+ setActiveTab: (tab: PanelTab) => void
59
+ setPageSettings: (settings: Partial<PageSettings>) => void
60
+ setShowGridOverlay: (show: boolean) => void
61
+
62
+ addSection: () => void
63
+ addRowToSection: (sectionId: string) => void
64
+ addBlockToColumn: (columnId: string, blockType: string, variant?: string) => void
65
+ addNodeAtId: (parentId: string, node: BuilderNode, index?: number) => void
66
+ removeNodeById: (id: string) => void
67
+ moveNodeById: (id: string, newParentId: string, index?: number) => void
68
+ updateSettings: (id: string, settings: Record<string, unknown>) => void
69
+ updateBlock: (id: string, data: Record<string, unknown>) => void
70
+ duplicateNode: (id: string) => void
71
+ moveNodeUp: (id: string) => void
72
+ moveNodeDown: (id: string) => void
73
+
74
+ undo: () => void
75
+ redo: () => void
76
+ markClean: () => void
77
+ replaceTree: (tree: PageNode) => void
78
78
  }
79
79
 
80
- const MAX_HISTORY = 50;
80
+ const MAX_HISTORY = 50
81
81
 
82
82
  function deepClone<T>(obj: T): T {
83
- return JSON.parse(JSON.stringify(obj));
83
+ return JSON.parse(JSON.stringify(obj))
84
84
  }
85
85
 
86
86
  function regenerateIds(node: BuilderNode): BuilderNode {
87
- const cloned = deepClone(node);
88
- let counter = 0;
87
+ const cloned = deepClone(node)
88
+ let counter = 0
89
89
  function walk(n: any) {
90
- n.id = `node_${Date.now().toString(36)}_${(counter++).toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
90
+ n.id = `node_${Date.now().toString(36)}_${(counter++).toString(36)}_${Math.random().toString(36).slice(2, 8)}`
91
91
  if (Array.isArray(n.children)) {
92
- for (const child of n.children) walk(child);
92
+ for (const child of n.children) walk(child)
93
93
  }
94
94
  }
95
- walk(cloned);
96
- return cloned;
95
+ walk(cloned)
96
+ return cloned
97
97
  }
98
98
 
99
99
  export function useBuilderState(
100
100
  initialTree?: PageNode,
101
101
  initialPageSettings?: Partial<PageSettings>,
102
102
  ): BuilderState & BuilderActions {
103
- const [tree, setTree] = useState<PageNode>(() => initialTree ?? createEmptyPage());
104
- const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null);
105
- const [deviceMode, setDeviceMode] = useState<DeviceMode>('desktop');
106
- const [activeTab, setActiveTab] = useState<PanelTab>('page');
107
- const [showGridOverlay, setShowGridOverlay] = useState(false);
103
+ const [tree, setTree] = useState<PageNode>(() => initialTree ?? createEmptyPage())
104
+ const [selectedNodeId, setSelectedNodeId] = useState<string | null>(null)
105
+ const [deviceMode, setDeviceMode] = useState<DeviceMode>('desktop')
106
+ const [activeTab, setActiveTab] = useState<PanelTab>('page')
107
+ const [showGridOverlay, setShowGridOverlay] = useState(false)
108
108
  const [pageSettings, setPageSettingsState] = useState<PageSettings>({
109
109
  title: '',
110
110
  slug: '',
111
111
  ...initialPageSettings,
112
- });
113
- const [dirty, setDirty] = useState(false);
112
+ })
113
+ const [dirty, setDirty] = useState(false)
114
114
 
115
- const undoStack = useRef<PageNode[]>([]);
116
- const redoStack = useRef<PageNode[]>([]);
115
+ const undoStack = useRef<PageNode[]>([])
116
+ const redoStack = useRef<PageNode[]>([])
117
117
 
118
118
  const pushHistory = useCallback((currentTree: PageNode) => {
119
- undoStack.current = [...undoStack.current.slice(-MAX_HISTORY + 1), currentTree];
120
- redoStack.current = [];
121
- }, []);
122
-
123
- const [canUndo, setCanUndo] = useState(false);
124
- const [canRedo, setCanRedo] = useState(false);
125
-
126
- const applyTreeChange = useCallback((fn: (prev: PageNode) => PageNode) => {
127
- setTree((prev) => {
128
- pushHistory(prev);
129
- const next = fn(prev);
130
- setDirty(true);
131
- setCanUndo(true);
132
- setCanRedo(false);
133
- return next;
134
- });
135
- }, [pushHistory]);
119
+ undoStack.current = [...undoStack.current.slice(-MAX_HISTORY + 1), currentTree]
120
+ redoStack.current = []
121
+ }, [])
122
+
123
+ const [canUndo, setCanUndo] = useState(false)
124
+ const [canRedo, setCanRedo] = useState(false)
125
+
126
+ const applyTreeChange = useCallback(
127
+ (fn: (prev: PageNode) => PageNode) => {
128
+ setTree((prev) => {
129
+ pushHistory(prev)
130
+ const next = fn(prev)
131
+ setDirty(true)
132
+ setCanUndo(true)
133
+ setCanRedo(false)
134
+ return next
135
+ })
136
+ },
137
+ [pushHistory],
138
+ )
136
139
 
137
140
  const selectedNode = useMemo(() => {
138
- if (!selectedNodeId) return null;
139
- return findNode(tree, selectedNodeId) ?? null;
140
- }, [tree, selectedNodeId]);
141
-
142
- const selectNode = useCallback((id: string | null) => {
143
- setSelectedNodeId(id);
144
- if (id) {
145
- const node = findNode(tree, id);
146
- if (node) {
147
- if (node.type === 'block') setActiveTab('block');
148
- else if (node.type === 'page') setActiveTab('page');
149
- else setActiveTab('node');
141
+ if (!selectedNodeId) return null
142
+ return findNode(tree, selectedNodeId) ?? null
143
+ }, [tree, selectedNodeId])
144
+
145
+ const selectNode = useCallback(
146
+ (id: string | null) => {
147
+ setSelectedNodeId(id)
148
+ if (id) {
149
+ const node = findNode(tree, id)
150
+ if (node) {
151
+ if (node.type === 'block') setActiveTab('block')
152
+ else if (node.type === 'page') setActiveTab('page')
153
+ else setActiveTab('node')
154
+ }
150
155
  }
151
- }
152
- }, [tree]);
156
+ },
157
+ [tree],
158
+ )
153
159
 
154
160
  const setPageSettings = useCallback((settings: Partial<PageSettings>) => {
155
- setPageSettingsState((prev) => ({ ...prev, ...settings }));
156
- setDirty(true);
157
- }, []);
161
+ setPageSettingsState((prev) => ({ ...prev, ...settings }))
162
+ setDirty(true)
163
+ }, [])
158
164
 
159
165
  const addSection = useCallback(() => {
160
166
  applyTreeChange((prev) => {
161
- const section = createSection({ paddingTop: '64px', paddingBottom: '64px' });
162
- const container = createContainer();
163
- const col = createColumn(12);
164
- const row = createRow([col]);
165
- (container as any).children = [row];
166
- (section as any).children = [container];
167
- return addNode(prev, prev.id, section as BuilderNode);
168
- });
169
- }, [applyTreeChange]);
170
-
171
- const addRowToSection = useCallback((sectionId: string) => {
172
- applyTreeChange((prev) => {
173
- const section = findNode(prev, sectionId);
174
- if (!section || !hasChildren(section)) return prev;
175
- const containers = (section as SectionNode).children.filter((c) => c.type === 'container');
176
- const targetId = containers.length > 0 ? containers[containers.length - 1]!.id : sectionId;
177
- const col = createColumn(12);
178
- const row = createRow([col]);
179
- return addNode(prev, targetId, row as BuilderNode);
180
- });
181
- }, [applyTreeChange]);
182
-
183
- const addBlockToColumn = useCallback((columnId: string, blockType: string, variant?: string) => {
184
- applyTreeChange((prev) => {
185
- const block = createBlock(blockType, variant);
186
- return addNode(prev, columnId, block as BuilderNode);
187
- });
188
- }, [applyTreeChange]);
189
-
190
- const addNodeAtId = useCallback((parentId: string, node: BuilderNode, index?: number) => {
191
- applyTreeChange((prev) => addNode(prev, parentId, node, index));
192
- }, [applyTreeChange]);
193
-
194
- const removeNodeById = useCallback((id: string) => {
195
- applyTreeChange((prev) => {
196
- const result = removeNode(prev, id);
197
- if (selectedNodeId === id) setSelectedNodeId(null);
198
- return result;
199
- });
200
- }, [applyTreeChange, selectedNodeId]);
201
-
202
- const moveNodeById = useCallback((id: string, newParentId: string, index?: number) => {
203
- applyTreeChange((prev) => moveNode(prev, id, newParentId, index));
204
- }, [applyTreeChange]);
205
-
206
- const updateSettings = useCallback((id: string, settings: Record<string, unknown>) => {
207
- applyTreeChange((prev) => updateNodeSettings(prev, id, settings));
208
- }, [applyTreeChange]);
209
-
210
- const updateBlock = useCallback((id: string, data: Record<string, unknown>) => {
211
- applyTreeChange((prev) => updateBlockData(prev, id, data));
212
- }, [applyTreeChange]);
213
-
214
- const duplicateNode = useCallback((id: string) => {
215
- applyTreeChange((prev) => {
216
- const node = findNode(prev, id);
217
- if (!node) return prev;
218
- const parent = findParent(prev, id);
219
- if (!parent) return prev;
220
- const siblings = (parent as any).children as BuilderNode[];
221
- const idx = siblings.findIndex((c) => c.id === id);
222
- const cloned = regenerateIds(node);
223
- return addNode(prev, parent.id, cloned, idx + 1);
224
- });
225
- }, [applyTreeChange]);
226
-
227
- const moveNodeUp = useCallback((id: string) => {
228
- applyTreeChange((prev) => {
229
- const parent = findParent(prev, id);
230
- if (!parent) return prev;
231
- const siblings = (parent as any).children as BuilderNode[];
232
- const idx = siblings.findIndex((c) => c.id === id);
233
- if (idx <= 0) return prev;
234
- const withoutNode = removeNode(prev, id);
235
- const node = findNode(prev, id);
236
- if (!node) return prev;
237
- return addNode(withoutNode, parent.id, deepClone(node), idx - 1);
238
- });
239
- }, [applyTreeChange]);
240
-
241
- const moveNodeDown = useCallback((id: string) => {
242
- applyTreeChange((prev) => {
243
- const parent = findParent(prev, id);
244
- if (!parent) return prev;
245
- const siblings = (parent as any).children as BuilderNode[];
246
- const idx = siblings.findIndex((c) => c.id === id);
247
- if (idx >= siblings.length - 1) return prev;
248
- const withoutNode = removeNode(prev, id);
249
- const node = findNode(prev, id);
250
- if (!node) return prev;
251
- return addNode(withoutNode, parent.id, deepClone(node), idx + 1);
252
- });
253
- }, [applyTreeChange]);
167
+ const section = createSection({ paddingTop: '64px', paddingBottom: '64px' })
168
+ const container = createContainer()
169
+ const col = createColumn(12)
170
+ const row = createRow([col])
171
+ ;(container as any).children = [row]
172
+ ;(section as any).children = [container]
173
+ return addNode(prev, prev.id, section as BuilderNode)
174
+ })
175
+ }, [applyTreeChange])
176
+
177
+ const addRowToSection = useCallback(
178
+ (sectionId: string) => {
179
+ applyTreeChange((prev) => {
180
+ const section = findNode(prev, sectionId)
181
+ if (!section || !hasChildren(section)) return prev
182
+ const containers = (section as SectionNode).children.filter((c) => c.type === 'container')
183
+ const targetId = containers.length > 0 ? containers[containers.length - 1]!.id : sectionId
184
+ const col = createColumn(12)
185
+ const row = createRow([col])
186
+ return addNode(prev, targetId, row as BuilderNode)
187
+ })
188
+ },
189
+ [applyTreeChange],
190
+ )
191
+
192
+ const addBlockToColumn = useCallback(
193
+ (columnId: string, blockType: string, variant?: string) => {
194
+ applyTreeChange((prev) => {
195
+ const block = createBlock(blockType, variant)
196
+ return addNode(prev, columnId, block as BuilderNode)
197
+ })
198
+ },
199
+ [applyTreeChange],
200
+ )
201
+
202
+ const addNodeAtId = useCallback(
203
+ (parentId: string, node: BuilderNode, index?: number) => {
204
+ applyTreeChange((prev) => addNode(prev, parentId, node, index))
205
+ },
206
+ [applyTreeChange],
207
+ )
208
+
209
+ const removeNodeById = useCallback(
210
+ (id: string) => {
211
+ applyTreeChange((prev) => {
212
+ const result = removeNode(prev, id)
213
+ if (selectedNodeId === id) setSelectedNodeId(null)
214
+ return result
215
+ })
216
+ },
217
+ [applyTreeChange, selectedNodeId],
218
+ )
219
+
220
+ const moveNodeById = useCallback(
221
+ (id: string, newParentId: string, index?: number) => {
222
+ applyTreeChange((prev) => moveNode(prev, id, newParentId, index))
223
+ },
224
+ [applyTreeChange],
225
+ )
226
+
227
+ const updateSettings = useCallback(
228
+ (id: string, settings: Record<string, unknown>) => {
229
+ applyTreeChange((prev) => updateNodeSettings(prev, id, settings))
230
+ },
231
+ [applyTreeChange],
232
+ )
233
+
234
+ const updateBlock = useCallback(
235
+ (id: string, data: Record<string, unknown>) => {
236
+ applyTreeChange((prev) => updateBlockData(prev, id, data))
237
+ },
238
+ [applyTreeChange],
239
+ )
240
+
241
+ const duplicateNode = useCallback(
242
+ (id: string) => {
243
+ applyTreeChange((prev) => {
244
+ const node = findNode(prev, id)
245
+ if (!node) return prev
246
+ const parent = findParent(prev, id)
247
+ if (!parent) return prev
248
+ const siblings = (parent as any).children as BuilderNode[]
249
+ const idx = siblings.findIndex((c) => c.id === id)
250
+ const cloned = regenerateIds(node)
251
+ return addNode(prev, parent.id, cloned, idx + 1)
252
+ })
253
+ },
254
+ [applyTreeChange],
255
+ )
256
+
257
+ const moveNodeUp = useCallback(
258
+ (id: string) => {
259
+ applyTreeChange((prev) => {
260
+ const parent = findParent(prev, id)
261
+ if (!parent) return prev
262
+ const siblings = (parent as any).children as BuilderNode[]
263
+ const idx = siblings.findIndex((c) => c.id === id)
264
+ if (idx <= 0) return prev
265
+ const withoutNode = removeNode(prev, id)
266
+ const node = findNode(prev, id)
267
+ if (!node) return prev
268
+ return addNode(withoutNode, parent.id, deepClone(node), idx - 1)
269
+ })
270
+ },
271
+ [applyTreeChange],
272
+ )
273
+
274
+ const moveNodeDown = useCallback(
275
+ (id: string) => {
276
+ applyTreeChange((prev) => {
277
+ const parent = findParent(prev, id)
278
+ if (!parent) return prev
279
+ const siblings = (parent as any).children as BuilderNode[]
280
+ const idx = siblings.findIndex((c) => c.id === id)
281
+ if (idx >= siblings.length - 1) return prev
282
+ const withoutNode = removeNode(prev, id)
283
+ const node = findNode(prev, id)
284
+ if (!node) return prev
285
+ return addNode(withoutNode, parent.id, deepClone(node), idx + 1)
286
+ })
287
+ },
288
+ [applyTreeChange],
289
+ )
254
290
 
255
291
  const undo = useCallback(() => {
256
- if (undoStack.current.length === 0) return;
257
- const prev = undoStack.current[undoStack.current.length - 1]!;
258
- undoStack.current = undoStack.current.slice(0, -1);
292
+ if (undoStack.current.length === 0) return
293
+ const prev = undoStack.current[undoStack.current.length - 1]!
294
+ undoStack.current = undoStack.current.slice(0, -1)
259
295
  setTree((current) => {
260
- redoStack.current = [...redoStack.current, current];
261
- setCanUndo(undoStack.current.length > 0);
262
- setCanRedo(true);
263
- return prev;
264
- });
265
- }, []);
296
+ redoStack.current = [...redoStack.current, current]
297
+ setCanUndo(undoStack.current.length > 0)
298
+ setCanRedo(true)
299
+ return prev
300
+ })
301
+ }, [])
266
302
 
267
303
  const redo = useCallback(() => {
268
- if (redoStack.current.length === 0) return;
269
- const next = redoStack.current[redoStack.current.length - 1]!;
270
- redoStack.current = redoStack.current.slice(0, -1);
304
+ if (redoStack.current.length === 0) return
305
+ const next = redoStack.current[redoStack.current.length - 1]!
306
+ redoStack.current = redoStack.current.slice(0, -1)
271
307
  setTree((current) => {
272
- undoStack.current = [...undoStack.current, current];
273
- setCanRedo(redoStack.current.length > 0);
274
- setCanUndo(true);
275
- return next;
276
- });
277
- }, []);
308
+ undoStack.current = [...undoStack.current, current]
309
+ setCanRedo(redoStack.current.length > 0)
310
+ setCanUndo(true)
311
+ return next
312
+ })
313
+ }, [])
278
314
 
279
315
  const markClean = useCallback(() => {
280
- setDirty(false);
281
- }, []);
282
-
283
- const replaceTree = useCallback((newTree: PageNode) => {
284
- setTree((prev) => {
285
- pushHistory(prev);
286
- setDirty(true);
287
- setCanUndo(true);
288
- setCanRedo(false);
289
- return newTree;
290
- });
291
- }, [pushHistory]);
316
+ setDirty(false)
317
+ }, [])
318
+
319
+ const replaceTree = useCallback(
320
+ (newTree: PageNode) => {
321
+ setTree((prev) => {
322
+ pushHistory(prev)
323
+ setDirty(true)
324
+ setCanUndo(true)
325
+ setCanRedo(false)
326
+ return newTree
327
+ })
328
+ },
329
+ [pushHistory],
330
+ )
292
331
 
293
332
  return {
294
333
  tree,
@@ -324,5 +363,5 @@ export function useBuilderState(
324
363
  redo,
325
364
  markClean,
326
365
  replaceTree,
327
- };
366
+ }
328
367
  }
@@ -1,35 +1,38 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useEffect, useCallback } from 'react';
3
+ import { useState, useEffect, useCallback } from 'react'
4
4
 
5
5
  interface ContentLock {
6
- lockedBy: string | null;
7
- lockedAt: Date | null;
8
- isLocked: boolean;
9
- isLockedByMe: boolean;
6
+ lockedBy: string | null
7
+ lockedAt: Date | null
8
+ isLocked: boolean
9
+ isLockedByMe: boolean
10
10
  }
11
11
 
12
- export function useContentLock(documentId: string | undefined, userId: string): ContentLock & {
13
- acquireLock: () => Promise<boolean>;
14
- releaseLock: () => Promise<void>;
12
+ export function useContentLock(
13
+ documentId: string | undefined,
14
+ userId: string,
15
+ ): ContentLock & {
16
+ acquireLock: () => Promise<boolean>
17
+ releaseLock: () => Promise<void>
15
18
  } {
16
19
  const [lock, setLock] = useState<ContentLock>({
17
20
  lockedBy: null,
18
21
  lockedAt: null,
19
22
  isLocked: false,
20
23
  isLockedByMe: false,
21
- });
24
+ })
22
25
 
23
26
  const acquireLock = useCallback(async () => {
24
- if (!documentId) return false;
27
+ if (!documentId) return false
25
28
  setLock({
26
29
  lockedBy: userId,
27
30
  lockedAt: new Date(),
28
31
  isLocked: true,
29
32
  isLockedByMe: true,
30
- });
31
- return true;
32
- }, [documentId, userId]);
33
+ })
34
+ return true
35
+ }, [documentId, userId])
33
36
 
34
37
  const releaseLock = useCallback(async () => {
35
38
  setLock({
@@ -37,16 +40,16 @@ export function useContentLock(documentId: string | undefined, userId: string):
37
40
  lockedAt: null,
38
41
  isLocked: false,
39
42
  isLockedByMe: false,
40
- });
41
- }, []);
43
+ })
44
+ }, [])
42
45
 
43
46
  useEffect(() => {
44
47
  return () => {
45
48
  if (lock.isLockedByMe) {
46
- releaseLock();
49
+ releaseLock()
47
50
  }
48
- };
49
- }, [lock.isLockedByMe, releaseLock]);
51
+ }
52
+ }, [lock.isLockedByMe, releaseLock])
50
53
 
51
- return { ...lock, acquireLock, releaseLock };
54
+ return { ...lock, acquireLock, releaseLock }
52
55
  }
@@ -1,14 +1,14 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useEffect } from 'react';
3
+ import { useState, useEffect } from 'react'
4
4
 
5
5
  export function useDebounce<T>(value: T, delayMs: number): T {
6
- const [debouncedValue, setDebouncedValue] = useState(value);
6
+ const [debouncedValue, setDebouncedValue] = useState(value)
7
7
 
8
8
  useEffect(() => {
9
- const timer = setTimeout(() => setDebouncedValue(value), delayMs);
10
- return () => clearTimeout(timer);
11
- }, [value, delayMs]);
9
+ const timer = setTimeout(() => setDebouncedValue(value), delayMs)
10
+ return () => clearTimeout(timer)
11
+ }, [value, delayMs])
12
12
 
13
- return debouncedValue;
13
+ return debouncedValue
14
14
  }