@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,51 +1,46 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useEffect, useCallback } from 'react';
4
- import { Loader2, AlertTriangle } from 'lucide-react';
5
- import { toast } from 'sonner';
6
- import { cmsApi } from '../../lib/api.js';
7
- import { ErrorBoundary } from '../../components/ErrorBoundary.js';
3
+ import { useState, useEffect, useCallback } from 'react'
4
+ import { Loader2, AlertTriangle } from 'lucide-react'
5
+ import { toast } from 'sonner'
6
+ import { cmsApi } from '../../lib/api.js'
7
+ import { ErrorBoundary } from '../../components/ErrorBoundary.js'
8
8
  import {
9
9
  useBuilderState,
10
10
  type BuilderState,
11
11
  type BuilderActions,
12
12
  type PageSettings,
13
- } from '../../hooks/useBuilderState.js';
14
- import type { PageNode } from '@actuate-media/cms-core';
15
- import { BuilderToolbar } from './BuilderToolbar.js';
16
- import { BottomBar } from './BottomBar.js';
17
- import { BuilderCanvas } from './canvas/index.js';
18
- import { ContextPanel } from './ContextPanel.js';
19
- import { AIGenerateDialog } from './AIGenerateDialog.js';
13
+ } from '../../hooks/useBuilderState.js'
14
+ import type { PageNode } from '@actuate-media/cms-core'
15
+ import { BuilderToolbar } from './BuilderToolbar.js'
16
+ import { BottomBar } from './BottomBar.js'
17
+ import { BuilderCanvas } from './canvas/index.js'
18
+ import { ContextPanel } from './ContextPanel.js'
19
+ import { AIGenerateDialog } from './AIGenerateDialog.js'
20
20
 
21
21
  export interface PageBuilderProps {
22
- documentId?: string;
23
- collectionSlug: string;
24
- config: any;
25
- onNavigate: (path: string) => void;
22
+ documentId?: string
23
+ collectionSlug: string
24
+ config: any
25
+ onNavigate: (path: string) => void
26
26
  }
27
27
 
28
- type DocumentStatus = 'DRAFT' | 'PUBLISHED' | 'SCHEDULED';
28
+ type DocumentStatus = 'DRAFT' | 'PUBLISHED' | 'SCHEDULED'
29
29
 
30
30
  const DEVICE_WIDTHS = {
31
31
  desktop: '100%',
32
32
  tablet: '768px',
33
33
  mobile: '375px',
34
- } as const;
34
+ } as const
35
35
 
36
- export function PageBuilder({
37
- documentId,
38
- collectionSlug,
39
- config,
40
- onNavigate,
41
- }: PageBuilderProps) {
42
- const [loading, setLoading] = useState(!!documentId);
43
- const [loadError, setLoadError] = useState<string | null>(null);
44
- const [saving, setSaving] = useState(false);
45
- const [status, setStatus] = useState<DocumentStatus>('DRAFT');
46
- const [aiDialogOpen, setAiDialogOpen] = useState(false);
36
+ export function PageBuilder({ documentId, collectionSlug, config, onNavigate }: PageBuilderProps) {
37
+ const [loading, setLoading] = useState(!!documentId)
38
+ const [loadError, setLoadError] = useState<string | null>(null)
39
+ const [saving, setSaving] = useState(false)
40
+ const [status, setStatus] = useState<DocumentStatus>('DRAFT')
41
+ const [aiDialogOpen, setAiDialogOpen] = useState(false)
47
42
 
48
- const builder = useBuilderState();
43
+ const builder = useBuilderState()
49
44
  const {
50
45
  tree,
51
46
  pageSettings,
@@ -77,117 +72,122 @@ export function PageBuilder({
77
72
  redo,
78
73
  markClean,
79
74
  replaceTree,
80
- } = builder;
75
+ } = builder
81
76
 
82
77
  useEffect(() => {
83
78
  if (!documentId) {
84
- setLoading(false);
85
- return;
79
+ setLoading(false)
80
+ return
86
81
  }
87
82
 
88
- let cancelled = false;
83
+ let cancelled = false
89
84
 
90
85
  async function loadDocument() {
91
- const res = await cmsApi<any>(`/collections/${collectionSlug}/${documentId}`);
86
+ const res = await cmsApi<any>(`/collections/${collectionSlug}/${documentId}`)
92
87
 
93
- if (cancelled) return;
88
+ if (cancelled) return
94
89
 
95
90
  if (res.error) {
96
- setLoadError(res.error);
97
- setLoading(false);
98
- return;
91
+ setLoadError(res.error)
92
+ setLoading(false)
93
+ return
99
94
  }
100
95
 
101
- const doc = res.data;
96
+ const doc = res.data
102
97
  if (doc?.layout) {
103
- replaceTree(doc.layout as PageNode);
104
- markClean();
98
+ replaceTree(doc.layout as PageNode)
99
+ markClean()
105
100
  }
106
101
  if (doc?.pageSettings) {
107
- setPageSettings(doc.pageSettings);
102
+ setPageSettings(doc.pageSettings)
108
103
  }
109
104
  if (doc?.status) {
110
- setStatus(doc.status as DocumentStatus);
105
+ setStatus(doc.status as DocumentStatus)
111
106
  }
112
107
  if (doc?.title) {
113
- setPageSettings({ title: doc.title });
108
+ setPageSettings({ title: doc.title })
114
109
  }
115
110
 
116
- setLoading(false);
111
+ setLoading(false)
117
112
  }
118
113
 
119
- loadDocument();
120
- return () => { cancelled = true; };
121
- }, [documentId, collectionSlug]);
114
+ loadDocument()
115
+ return () => {
116
+ cancelled = true
117
+ }
118
+ }, [documentId, collectionSlug])
122
119
 
123
120
  const handleSave = useCallback(async () => {
124
- setSaving(true);
121
+ setSaving(true)
125
122
  const body = JSON.stringify({
126
123
  layout: tree,
127
124
  pageSettings,
128
125
  title: pageSettings.title,
129
126
  slug: pageSettings.slug,
130
- });
127
+ })
131
128
 
132
129
  const endpoint = documentId
133
130
  ? `/collections/${collectionSlug}/${documentId}`
134
- : `/collections/${collectionSlug}`;
135
- const method = documentId ? 'PUT' : 'POST';
131
+ : `/collections/${collectionSlug}`
132
+ const method = documentId ? 'PUT' : 'POST'
136
133
 
137
- const res = await cmsApi(endpoint, { method, body });
138
- setSaving(false);
134
+ const res = await cmsApi(endpoint, { method, body })
135
+ setSaving(false)
139
136
 
140
137
  if (res.error) {
141
- toast.error(res.error);
138
+ toast.error(res.error)
142
139
  } else {
143
- markClean();
144
- toast.success('Page saved');
140
+ markClean()
141
+ toast.success('Page saved')
145
142
  if (!documentId && (res.data as any)?.id) {
146
- onNavigate(`/pages/${(res.data as any).id}/builder`);
143
+ onNavigate(`/pages/${(res.data as any).id}/builder`)
147
144
  }
148
145
  }
149
- }, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate]);
146
+ }, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate])
150
147
 
151
148
  const handlePublish = useCallback(async () => {
152
- setSaving(true);
149
+ setSaving(true)
153
150
  const body = JSON.stringify({
154
151
  layout: tree,
155
152
  pageSettings,
156
153
  title: pageSettings.title,
157
154
  slug: pageSettings.slug,
158
155
  status: 'PUBLISHED',
159
- });
156
+ })
160
157
 
161
158
  const endpoint = documentId
162
159
  ? `/collections/${collectionSlug}/${documentId}`
163
- : `/collections/${collectionSlug}`;
164
- const method = documentId ? 'PUT' : 'POST';
160
+ : `/collections/${collectionSlug}`
161
+ const method = documentId ? 'PUT' : 'POST'
165
162
 
166
- const res = await cmsApi(endpoint, { method, body });
167
- setSaving(false);
163
+ const res = await cmsApi(endpoint, { method, body })
164
+ setSaving(false)
168
165
 
169
166
  if (res.error) {
170
- toast.error(res.error);
167
+ toast.error(res.error)
171
168
  } else {
172
- markClean();
173
- setStatus('PUBLISHED');
174
- toast.success('Page published');
169
+ markClean()
170
+ setStatus('PUBLISHED')
171
+ toast.success('Page published')
175
172
  if (!documentId && (res.data as any)?.id) {
176
- onNavigate(`/pages/${(res.data as any).id}/builder`);
173
+ onNavigate(`/pages/${(res.data as any).id}/builder`)
177
174
  }
178
175
  }
179
- }, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate]);
176
+ }, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate])
180
177
 
181
- const handleAIAccept = useCallback((generatedTree: PageNode) => {
182
- replaceTree(generatedTree);
183
- }, [replaceTree]);
178
+ const handleAIAccept = useCallback(
179
+ (generatedTree: PageNode) => {
180
+ replaceTree(generatedTree)
181
+ },
182
+ [replaceTree],
183
+ )
184
184
 
185
185
  if (loading) {
186
186
  return (
187
187
  <div className="h-full flex items-center justify-center bg-background">
188
188
  <Loader2 className="animate-spin text-muted-foreground" size={24} />
189
189
  </div>
190
- );
190
+ )
191
191
  }
192
192
 
193
193
  if (loadError) {
@@ -201,105 +201,106 @@ export function PageBuilder({
201
201
  </div>
202
202
  </div>
203
203
  </div>
204
- );
204
+ )
205
205
  }
206
206
 
207
- const canvasWidth = DEVICE_WIDTHS[deviceMode];
208
- const isConstrained = deviceMode !== 'desktop';
207
+ const canvasWidth = DEVICE_WIDTHS[deviceMode]
208
+ const isConstrained = deviceMode !== 'desktop'
209
209
 
210
210
  // `pageBuilder.previewTheme` lets consumers preview blocks with their
211
211
  // brand fonts/colors/radii without baking them into the admin's tokens.
212
212
  // We scope the CSS variables to the canvas wrapper so they never leak
213
213
  // into the rest of the admin chrome.
214
- const previewTheme = config?.pageBuilder?.previewTheme ?? {};
215
- const previewStyle: Record<string, string> = {};
216
- if (previewTheme.fontFamily) previewStyle['--preview-font-family'] = previewTheme.fontFamily;
217
- if (previewTheme.headingFontFamily) previewStyle['--preview-heading-font-family'] = previewTheme.headingFontFamily;
218
- if (previewTheme.primaryColor) previewStyle['--preview-primary'] = previewTheme.primaryColor;
219
- if (previewTheme.secondaryColor) previewStyle['--preview-secondary'] = previewTheme.secondaryColor;
220
- if (previewTheme.borderRadius) previewStyle['--preview-radius'] = previewTheme.borderRadius;
214
+ const previewTheme = config?.pageBuilder?.previewTheme ?? {}
215
+ const previewStyle: Record<string, string> = {}
216
+ if (previewTheme.fontFamily) previewStyle['--preview-font-family'] = previewTheme.fontFamily
217
+ if (previewTheme.headingFontFamily)
218
+ previewStyle['--preview-heading-font-family'] = previewTheme.headingFontFamily
219
+ if (previewTheme.primaryColor) previewStyle['--preview-primary'] = previewTheme.primaryColor
220
+ if (previewTheme.secondaryColor) previewStyle['--preview-secondary'] = previewTheme.secondaryColor
221
+ if (previewTheme.borderRadius) previewStyle['--preview-radius'] = previewTheme.borderRadius
221
222
  const canvasShellStyle: React.CSSProperties = {
222
223
  ...previewStyle,
223
224
  fontFamily: previewTheme.fontFamily ?? undefined,
224
- };
225
+ }
225
226
 
226
227
  return (
227
228
  <ErrorBoundary>
228
- <div className="h-full flex flex-col bg-background overflow-hidden">
229
- <BuilderToolbar
230
- collectionSlug={collectionSlug}
231
- pageSettings={pageSettings}
232
- status={status}
233
- dirty={dirty}
234
- saving={saving}
235
- canUndo={canUndo}
236
- canRedo={canRedo}
237
- deviceMode={deviceMode}
238
- onNavigate={onNavigate}
239
- onTitleChange={(title) => setPageSettings({ title })}
240
- onUndo={undo}
241
- onRedo={redo}
242
- onDeviceMode={setDeviceMode}
243
- onSave={handleSave}
244
- onPublish={handlePublish}
245
- onOpenAI={() => setAiDialogOpen(true)}
246
- />
229
+ <div className="h-full flex flex-col bg-background overflow-hidden">
230
+ <BuilderToolbar
231
+ collectionSlug={collectionSlug}
232
+ pageSettings={pageSettings}
233
+ status={status}
234
+ dirty={dirty}
235
+ saving={saving}
236
+ canUndo={canUndo}
237
+ canRedo={canRedo}
238
+ deviceMode={deviceMode}
239
+ onNavigate={onNavigate}
240
+ onTitleChange={(title) => setPageSettings({ title })}
241
+ onUndo={undo}
242
+ onRedo={redo}
243
+ onDeviceMode={setDeviceMode}
244
+ onSave={handleSave}
245
+ onPublish={handlePublish}
246
+ onOpenAI={() => setAiDialogOpen(true)}
247
+ />
247
248
 
248
- <div className="flex-1 flex overflow-hidden">
249
- {/* Canvas area */}
250
- <div className="flex-1 overflow-auto bg-muted">
251
- <div
252
- className="mx-auto h-full max-w-full transition-all duration-200"
253
- style={{ width: canvasWidth }}
254
- >
249
+ <div className="flex-1 flex overflow-hidden">
250
+ {/* Canvas area */}
251
+ <div className="flex-1 overflow-auto bg-muted">
255
252
  <div
256
- className={`h-full bg-background page-builder-canvas-shell ${isConstrained ? 'shadow-lg border-x border-border' : ''}`}
257
- style={canvasShellStyle}
253
+ className="mx-auto h-full max-w-full transition-all duration-200"
254
+ style={{ width: canvasWidth }}
258
255
  >
259
- <BuilderCanvas
260
- tree={tree}
261
- selectedNodeId={selectedNodeId}
262
- showGridOverlay={showGridOverlay}
263
- deviceMode={deviceMode}
264
- onSelectNode={selectNode}
265
- />
256
+ <div
257
+ className={`h-full bg-background page-builder-canvas-shell ${isConstrained ? 'shadow-lg border-x border-border' : ''}`}
258
+ style={canvasShellStyle}
259
+ >
260
+ <BuilderCanvas
261
+ tree={tree}
262
+ selectedNodeId={selectedNodeId}
263
+ showGridOverlay={showGridOverlay}
264
+ deviceMode={deviceMode}
265
+ onSelectNode={selectNode}
266
+ />
267
+ </div>
266
268
  </div>
267
269
  </div>
268
- </div>
269
270
 
270
- {/* Context panel */}
271
- <div className="w-[35%] min-w-[280px] max-w-[420px] border-l border-border bg-card overflow-y-auto">
272
- <ContextPanel
273
- activeTab={activeTab}
274
- onTabChange={setActiveTab}
275
- selectedNode={selectedNode}
276
- tree={tree}
277
- pageSettings={pageSettings}
278
- onUpdateSettings={updateSettings}
279
- onUpdateBlock={updateBlock}
280
- onRemoveNode={removeNodeById}
281
- onDuplicateNode={duplicateNode}
282
- onMoveNodeUp={moveNodeUp}
283
- onMoveNodeDown={moveNodeDown}
284
- onPageSettingsChange={setPageSettings}
285
- onAddRow={addRowToSection}
286
- config={config}
287
- />
271
+ {/* Context panel */}
272
+ <div className="w-[35%] min-w-[280px] max-w-[420px] border-l border-border bg-card overflow-y-auto">
273
+ <ContextPanel
274
+ activeTab={activeTab}
275
+ onTabChange={setActiveTab}
276
+ selectedNode={selectedNode}
277
+ tree={tree}
278
+ pageSettings={pageSettings}
279
+ onUpdateSettings={updateSettings}
280
+ onUpdateBlock={updateBlock}
281
+ onRemoveNode={removeNodeById}
282
+ onDuplicateNode={duplicateNode}
283
+ onMoveNodeUp={moveNodeUp}
284
+ onMoveNodeDown={moveNodeDown}
285
+ onPageSettingsChange={setPageSettings}
286
+ onAddRow={addRowToSection}
287
+ config={config}
288
+ />
289
+ </div>
288
290
  </div>
289
- </div>
290
291
 
291
- <BottomBar
292
- deviceMode={deviceMode}
293
- showGridOverlay={showGridOverlay}
294
- onAddSection={addSection}
295
- onToggleGrid={setShowGridOverlay}
292
+ <BottomBar
293
+ deviceMode={deviceMode}
294
+ showGridOverlay={showGridOverlay}
295
+ onAddSection={addSection}
296
+ onToggleGrid={setShowGridOverlay}
297
+ />
298
+ </div>
299
+ <AIGenerateDialog
300
+ open={aiDialogOpen}
301
+ onClose={() => setAiDialogOpen(false)}
302
+ onAccept={handleAIAccept}
296
303
  />
297
- </div>
298
- <AIGenerateDialog
299
- open={aiDialogOpen}
300
- onClose={() => setAiDialogOpen(false)}
301
- onAccept={handleAIAccept}
302
- />
303
304
  </ErrorBoundary>
304
- );
305
+ )
305
306
  }
@@ -1,17 +1,18 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useCallback } from 'react';
4
- import type { PageSettings } from '../../hooks/useBuilderState.js';
3
+ import { useCallback } from 'react'
4
+ import type { PageSettings } from '../../hooks/useBuilderState.js'
5
5
 
6
6
  export interface PageSettingsProps {
7
- settings: PageSettings;
8
- onChange: (settings: Partial<PageSettings>) => void;
7
+ settings: PageSettings
8
+ onChange: (settings: Partial<PageSettings>) => void
9
9
  }
10
10
 
11
11
  const INPUT_CLASS =
12
- 'w-full px-3 py-2 text-sm bg-background border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring';
13
- const LABEL_CLASS = 'text-sm font-medium text-foreground mb-1 block';
14
- const SECTION_HEADING_CLASS = 'text-xs font-medium uppercase tracking-wider text-muted-foreground mb-2';
12
+ 'w-full px-3 py-2 text-sm bg-background border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring'
13
+ const LABEL_CLASS = 'text-sm font-medium text-foreground mb-1 block'
14
+ const SECTION_HEADING_CLASS =
15
+ 'text-xs font-medium uppercase tracking-wider text-muted-foreground mb-2'
15
16
 
16
17
  const SCHEMA_TYPES = [
17
18
  'Article',
@@ -24,18 +25,18 @@ const SCHEMA_TYPES = [
24
25
  'Recipe',
25
26
  'HowTo',
26
27
  'BreadcrumbList',
27
- ];
28
+ ]
28
29
 
29
30
  export function PageSettingsEditor({ settings, onChange }: PageSettingsProps) {
30
31
  const update = useCallback(
31
32
  (key: keyof PageSettings, value: string) => {
32
- onChange({ [key]: value });
33
+ onChange({ [key]: value })
33
34
  },
34
- [onChange]
35
- );
35
+ [onChange],
36
+ )
36
37
 
37
- const metaTitleLength = (settings.metaTitle ?? '').length;
38
- const metaDescLength = (settings.metaDescription ?? '').length;
38
+ const metaTitleLength = (settings.metaTitle ?? '').length
39
+ const metaDescLength = (settings.metaDescription ?? '').length
39
40
 
40
41
  return (
41
42
  <div className="space-y-4 p-4">
@@ -157,5 +158,5 @@ export function PageSettingsEditor({ settings, onChange }: PageSettingsProps) {
157
158
  </select>
158
159
  </div>
159
160
  </div>
160
- );
161
+ )
161
162
  }
@@ -1,24 +1,24 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { AlertTriangle, Layers, Loader2, RefreshCw } from 'lucide-react';
4
- import { useApiData } from '../../lib/useApiData.js';
3
+ import { AlertTriangle, Layers, Loader2, RefreshCw } from 'lucide-react'
4
+ import { useApiData } from '../../lib/useApiData.js'
5
5
 
6
6
  interface PageTemplate {
7
- id: string;
8
- name?: string;
9
- description?: string | null;
10
- category?: string;
11
- builtIn?: boolean;
12
- updatedAt?: string;
7
+ id: string
8
+ name?: string
9
+ description?: string | null
10
+ category?: string
11
+ builtIn?: boolean
12
+ updatedAt?: string
13
13
  }
14
14
 
15
15
  export interface PageTemplatesProps {
16
- onNavigate?: (path: string) => void;
16
+ onNavigate?: (path: string) => void
17
17
  }
18
18
 
19
19
  export function PageTemplates({ onNavigate }: PageTemplatesProps) {
20
- const { data, loading, error, refetch } = useApiData<PageTemplate[]>('/page-templates');
21
- const templates = data ?? [];
20
+ const { data, loading, error, refetch } = useApiData<PageTemplate[]>('/page-templates')
21
+ const templates = data ?? []
22
22
 
23
23
  if (loading) {
24
24
  return (
@@ -26,7 +26,7 @@ export function PageTemplates({ onNavigate }: PageTemplatesProps) {
26
26
  <Loader2 className="h-6 w-6 animate-spin text-primary" />
27
27
  <span className="sr-only">Loading page templates</span>
28
28
  </div>
29
- );
29
+ )
30
30
  }
31
31
 
32
32
  return (
@@ -83,8 +83,12 @@ export function PageTemplates({ onNavigate }: PageTemplatesProps) {
83
83
  <div key={template.id} className="rounded-lg border border-border bg-card p-4">
84
84
  <div className="mb-3 flex items-start justify-between gap-3">
85
85
  <div>
86
- <h2 className="text-base font-medium text-foreground">{template.name ?? 'Untitled template'}</h2>
87
- <p className="mt-1 text-sm text-muted-foreground">{template.description ?? 'No description provided.'}</p>
86
+ <h2 className="text-base font-medium text-foreground">
87
+ {template.name ?? 'Untitled template'}
88
+ </h2>
89
+ <p className="mt-1 text-sm text-muted-foreground">
90
+ {template.description ?? 'No description provided.'}
91
+ </p>
88
92
  </div>
89
93
  {template.builtIn && (
90
94
  <span className="rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
@@ -94,12 +98,14 @@ export function PageTemplates({ onNavigate }: PageTemplatesProps) {
94
98
  </div>
95
99
  <div className="flex items-center justify-between text-sm text-muted-foreground">
96
100
  <span>{template.category ?? 'content'}</span>
97
- <span>{template.updatedAt ? new Date(template.updatedAt).toLocaleDateString() : ''}</span>
101
+ <span>
102
+ {template.updatedAt ? new Date(template.updatedAt).toLocaleDateString() : ''}
103
+ </span>
98
104
  </div>
99
105
  </div>
100
106
  ))}
101
107
  </div>
102
108
  )}
103
109
  </div>
104
- );
110
+ )
105
111
  }