@actuate-media/cms-admin 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +44 -42
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/lib/search.test.js +10 -10
  5. package/dist/__tests__/lib/search.test.js.map +1 -1
  6. package/dist/__tests__/lib/utils.test.js.map +1 -1
  7. package/dist/__tests__/router/match-route.test.js.map +1 -1
  8. package/dist/__tests__/router/strip-base.test.js.map +1 -1
  9. package/dist/actuate-admin.css +1 -1
  10. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  11. package/dist/components/Breadcrumbs.js +2 -4
  12. package/dist/components/Breadcrumbs.js.map +1 -1
  13. package/dist/components/CommandPalette.d.ts.map +1 -1
  14. package/dist/components/CommandPalette.js +7 -3
  15. package/dist/components/CommandPalette.js.map +1 -1
  16. package/dist/components/ContentOverviewChart.d.ts.map +1 -1
  17. package/dist/components/ContentOverviewChart.js.map +1 -1
  18. package/dist/components/ErrorBoundary.d.ts.map +1 -1
  19. package/dist/components/ErrorBoundary.js.map +1 -1
  20. package/dist/components/FocalPointPicker.d.ts.map +1 -1
  21. package/dist/components/FocalPointPicker.js +4 -2
  22. package/dist/components/FocalPointPicker.js.map +1 -1
  23. package/dist/components/FolderTree.d.ts.map +1 -1
  24. package/dist/components/FolderTree.js +18 -10
  25. package/dist/components/FolderTree.js.map +1 -1
  26. package/dist/components/LivePreview.d.ts +1 -1
  27. package/dist/components/LivePreview.d.ts.map +1 -1
  28. package/dist/components/LivePreview.js +6 -2
  29. package/dist/components/LivePreview.js.map +1 -1
  30. package/dist/components/LocaleProvider.d.ts.map +1 -1
  31. package/dist/components/LocaleProvider.js.map +1 -1
  32. package/dist/components/LocaleSwitcher.d.ts.map +1 -1
  33. package/dist/components/LocaleSwitcher.js +1 -1
  34. package/dist/components/LocaleSwitcher.js.map +1 -1
  35. package/dist/components/MediaPickerModal.d.ts.map +1 -1
  36. package/dist/components/MediaPickerModal.js.map +1 -1
  37. package/dist/components/PresenceIndicator.d.ts.map +1 -1
  38. package/dist/components/PresenceIndicator.js +5 -2
  39. package/dist/components/PresenceIndicator.js.map +1 -1
  40. package/dist/components/SEOPanel.d.ts +1 -1
  41. package/dist/components/SEOPanel.d.ts.map +1 -1
  42. package/dist/components/SEOPanel.js +110 -24
  43. package/dist/components/SEOPanel.js.map +1 -1
  44. package/dist/components/SEOPerformance.d.ts.map +1 -1
  45. package/dist/components/SEOPerformance.js +2 -2
  46. package/dist/components/SEOPerformance.js.map +1 -1
  47. package/dist/components/ThemeProvider.d.ts.map +1 -1
  48. package/dist/components/ThemeProvider.js.map +1 -1
  49. package/dist/components/TipTapEditor.d.ts.map +1 -1
  50. package/dist/components/TipTapEditor.js +5 -1
  51. package/dist/components/TipTapEditor.js.map +1 -1
  52. package/dist/components/VersionHistory.d.ts +1 -1
  53. package/dist/components/VersionHistory.d.ts.map +1 -1
  54. package/dist/components/VersionHistory.js +1 -1
  55. package/dist/components/VersionHistory.js.map +1 -1
  56. package/dist/components/ui/Avatar.d.ts.map +1 -1
  57. package/dist/components/ui/Avatar.js.map +1 -1
  58. package/dist/components/ui/Badge.d.ts.map +1 -1
  59. package/dist/components/ui/Badge.js.map +1 -1
  60. package/dist/components/ui/Button.d.ts.map +1 -1
  61. package/dist/components/ui/Button.js.map +1 -1
  62. package/dist/components/ui/CommandPalette.d.ts.map +1 -1
  63. package/dist/components/ui/CommandPalette.js +8 -2
  64. package/dist/components/ui/CommandPalette.js.map +1 -1
  65. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -1
  66. package/dist/components/ui/ConfirmDialog.js.map +1 -1
  67. package/dist/components/ui/DataTable.d.ts.map +1 -1
  68. package/dist/components/ui/DataTable.js +1 -3
  69. package/dist/components/ui/DataTable.js.map +1 -1
  70. package/dist/components/ui/EmptyState.d.ts.map +1 -1
  71. package/dist/components/ui/EmptyState.js +1 -1
  72. package/dist/components/ui/EmptyState.js.map +1 -1
  73. package/dist/components/ui/Modal.d.ts.map +1 -1
  74. package/dist/components/ui/Modal.js.map +1 -1
  75. package/dist/components/ui/Pagination.d.ts +1 -1
  76. package/dist/components/ui/Pagination.d.ts.map +1 -1
  77. package/dist/components/ui/Pagination.js +7 -2
  78. package/dist/components/ui/Pagination.js.map +1 -1
  79. package/dist/components/ui/SearchInput.d.ts.map +1 -1
  80. package/dist/components/ui/SearchInput.js.map +1 -1
  81. package/dist/components/ui/Skeleton.d.ts.map +1 -1
  82. package/dist/components/ui/Skeleton.js.map +1 -1
  83. package/dist/components/ui/Toast.d.ts.map +1 -1
  84. package/dist/components/ui/Toast.js.map +1 -1
  85. package/dist/components/ui/index.d.ts.map +1 -1
  86. package/dist/components/ui/index.js.map +1 -1
  87. package/dist/fields/ArrayField.d.ts.map +1 -1
  88. package/dist/fields/ArrayField.js +1 -1
  89. package/dist/fields/ArrayField.js.map +1 -1
  90. package/dist/fields/BlockBuilderField.d.ts.map +1 -1
  91. package/dist/fields/BlockBuilderField.js +7 -7
  92. package/dist/fields/BlockBuilderField.js.map +1 -1
  93. package/dist/fields/DateField.d.ts.map +1 -1
  94. package/dist/fields/DateField.js +1 -1
  95. package/dist/fields/DateField.js.map +1 -1
  96. package/dist/fields/FieldRenderer.d.ts.map +1 -1
  97. package/dist/fields/FieldRenderer.js.map +1 -1
  98. package/dist/fields/GroupField.d.ts.map +1 -1
  99. package/dist/fields/GroupField.js +1 -1
  100. package/dist/fields/GroupField.js.map +1 -1
  101. package/dist/fields/MediaField.d.ts.map +1 -1
  102. package/dist/fields/MediaField.js +1 -1
  103. package/dist/fields/MediaField.js.map +1 -1
  104. package/dist/fields/NavBuilderField.d.ts.map +1 -1
  105. package/dist/fields/NavBuilderField.js +2 -5
  106. package/dist/fields/NavBuilderField.js.map +1 -1
  107. package/dist/fields/NumberField.d.ts +1 -1
  108. package/dist/fields/NumberField.d.ts.map +1 -1
  109. package/dist/fields/NumberField.js +2 -2
  110. package/dist/fields/NumberField.js.map +1 -1
  111. package/dist/fields/RelationshipField.d.ts.map +1 -1
  112. package/dist/fields/RelationshipField.js +7 -3
  113. package/dist/fields/RelationshipField.js.map +1 -1
  114. package/dist/fields/RichTextField.d.ts +1 -1
  115. package/dist/fields/RichTextField.d.ts.map +1 -1
  116. package/dist/fields/RichTextField.js +2 -2
  117. package/dist/fields/RichTextField.js.map +1 -1
  118. package/dist/fields/SelectField.d.ts.map +1 -1
  119. package/dist/fields/SelectField.js +9 -7
  120. package/dist/fields/SelectField.js.map +1 -1
  121. package/dist/fields/SlugField.d.ts.map +1 -1
  122. package/dist/fields/SlugField.js +1 -1
  123. package/dist/fields/SlugField.js.map +1 -1
  124. package/dist/fields/TextField.d.ts +1 -1
  125. package/dist/fields/TextField.d.ts.map +1 -1
  126. package/dist/fields/TextField.js +2 -2
  127. package/dist/fields/TextField.js.map +1 -1
  128. package/dist/fields/ToggleField.d.ts.map +1 -1
  129. package/dist/fields/ToggleField.js +1 -1
  130. package/dist/fields/ToggleField.js.map +1 -1
  131. package/dist/fields/block-types.d.ts.map +1 -1
  132. package/dist/fields/block-types.js +28 -8
  133. package/dist/fields/block-types.js.map +1 -1
  134. package/dist/fields/index.d.ts.map +1 -1
  135. package/dist/fields/index.js.map +1 -1
  136. package/dist/hooks/useBuilderState.d.ts.map +1 -1
  137. package/dist/hooks/useBuilderState.js.map +1 -1
  138. package/dist/hooks/useContentLock.d.ts.map +1 -1
  139. package/dist/hooks/useContentLock.js.map +1 -1
  140. package/dist/hooks/useDebounce.js.map +1 -1
  141. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -1
  142. package/dist/hooks/useKeyboardShortcuts.js.map +1 -1
  143. package/dist/index.d.ts +2 -2
  144. package/dist/index.d.ts.map +1 -1
  145. package/dist/index.js.map +1 -1
  146. package/dist/layout/Header.d.ts.map +1 -1
  147. package/dist/layout/Header.js.map +1 -1
  148. package/dist/layout/Layout.d.ts.map +1 -1
  149. package/dist/layout/Layout.js.map +1 -1
  150. package/dist/layout/Sidebar.d.ts +1 -1
  151. package/dist/layout/Sidebar.d.ts.map +1 -1
  152. package/dist/layout/Sidebar.js +5 -8
  153. package/dist/layout/Sidebar.js.map +1 -1
  154. package/dist/lib/api.js.map +1 -1
  155. package/dist/lib/search.d.ts.map +1 -1
  156. package/dist/lib/search.js +3 -5
  157. package/dist/lib/search.js.map +1 -1
  158. package/dist/lib/useApiData.d.ts.map +1 -1
  159. package/dist/lib/useApiData.js.map +1 -1
  160. package/dist/lib/utils.d.ts.map +1 -1
  161. package/dist/lib/utils.js.map +1 -1
  162. package/dist/router/index.d.ts.map +1 -1
  163. package/dist/router/index.js +1 -3
  164. package/dist/router/index.js.map +1 -1
  165. package/dist/views/CollectionList.d.ts.map +1 -1
  166. package/dist/views/CollectionList.js +56 -17
  167. package/dist/views/CollectionList.js.map +1 -1
  168. package/dist/views/Dashboard.d.ts.map +1 -1
  169. package/dist/views/Dashboard.js +26 -13
  170. package/dist/views/Dashboard.js.map +1 -1
  171. package/dist/views/DocumentEdit.d.ts +1 -1
  172. package/dist/views/DocumentEdit.d.ts.map +1 -1
  173. package/dist/views/DocumentEdit.js +33 -15
  174. package/dist/views/DocumentEdit.js.map +1 -1
  175. package/dist/views/ForgotPassword.d.ts.map +1 -1
  176. package/dist/views/ForgotPassword.js.map +1 -1
  177. package/dist/views/FormEditor.d.ts.map +1 -1
  178. package/dist/views/FormEditor.js +8 -2
  179. package/dist/views/FormEditor.js.map +1 -1
  180. package/dist/views/FormSubmissions.d.ts.map +1 -1
  181. package/dist/views/FormSubmissions.js +6 -6
  182. package/dist/views/FormSubmissions.js.map +1 -1
  183. package/dist/views/Forms.d.ts.map +1 -1
  184. package/dist/views/Forms.js.map +1 -1
  185. package/dist/views/Login.d.ts.map +1 -1
  186. package/dist/views/Login.js +5 -2
  187. package/dist/views/Login.js.map +1 -1
  188. package/dist/views/MediaBrowser.d.ts.map +1 -1
  189. package/dist/views/MediaBrowser.js +39 -19
  190. package/dist/views/MediaBrowser.js.map +1 -1
  191. package/dist/views/PageEditor.d.ts.map +1 -1
  192. package/dist/views/PageEditor.js.map +1 -1
  193. package/dist/views/Pages.d.ts.map +1 -1
  194. package/dist/views/Pages.js +20 -10
  195. package/dist/views/Pages.js.map +1 -1
  196. package/dist/views/PostEditor.d.ts.map +1 -1
  197. package/dist/views/PostEditor.js.map +1 -1
  198. package/dist/views/Posts.d.ts.map +1 -1
  199. package/dist/views/Posts.js +13 -7
  200. package/dist/views/Posts.js.map +1 -1
  201. package/dist/views/Redirects.d.ts.map +1 -1
  202. package/dist/views/Redirects.js +17 -5
  203. package/dist/views/Redirects.js.map +1 -1
  204. package/dist/views/ResetPassword.d.ts.map +1 -1
  205. package/dist/views/ResetPassword.js.map +1 -1
  206. package/dist/views/SEO.d.ts.map +1 -1
  207. package/dist/views/SEO.js +40 -17
  208. package/dist/views/SEO.js.map +1 -1
  209. package/dist/views/ScriptTagEditor.d.ts.map +1 -1
  210. package/dist/views/ScriptTagEditor.js +2 -1
  211. package/dist/views/ScriptTagEditor.js.map +1 -1
  212. package/dist/views/ScriptTags.d.ts.map +1 -1
  213. package/dist/views/ScriptTags.js.map +1 -1
  214. package/dist/views/Settings.d.ts.map +1 -1
  215. package/dist/views/Settings.js +38 -11
  216. package/dist/views/Settings.js.map +1 -1
  217. package/dist/views/SetupWizard.d.ts.map +1 -1
  218. package/dist/views/SetupWizard.js.map +1 -1
  219. package/dist/views/Users.d.ts.map +1 -1
  220. package/dist/views/Users.js +5 -3
  221. package/dist/views/Users.js.map +1 -1
  222. package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -1
  223. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  224. package/dist/views/page-builder/AIBlockAssist.js.map +1 -1
  225. package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -1
  226. package/dist/views/page-builder/AIGenerateDialog.js +4 -1
  227. package/dist/views/page-builder/AIGenerateDialog.js.map +1 -1
  228. package/dist/views/page-builder/BlockEditor.d.ts.map +1 -1
  229. package/dist/views/page-builder/BlockEditor.js +1 -1
  230. package/dist/views/page-builder/BlockEditor.js.map +1 -1
  231. package/dist/views/page-builder/BlockPicker.d.ts.map +1 -1
  232. package/dist/views/page-builder/BlockPicker.js.map +1 -1
  233. package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
  234. package/dist/views/page-builder/BottomBar.js.map +1 -1
  235. package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -1
  236. package/dist/views/page-builder/BuilderToolbar.js.map +1 -1
  237. package/dist/views/page-builder/ContextPanel.d.ts.map +1 -1
  238. package/dist/views/page-builder/ContextPanel.js +4 -1
  239. package/dist/views/page-builder/ContextPanel.js.map +1 -1
  240. package/dist/views/page-builder/DesignScore.d.ts.map +1 -1
  241. package/dist/views/page-builder/DesignScore.js.map +1 -1
  242. package/dist/views/page-builder/NodeSettings.d.ts.map +1 -1
  243. package/dist/views/page-builder/NodeSettings.js +1 -1
  244. package/dist/views/page-builder/NodeSettings.js.map +1 -1
  245. package/dist/views/page-builder/PageBuilder.d.ts +1 -1
  246. package/dist/views/page-builder/PageBuilder.d.ts.map +1 -1
  247. package/dist/views/page-builder/PageBuilder.js +4 -2
  248. package/dist/views/page-builder/PageBuilder.js.map +1 -1
  249. package/dist/views/page-builder/PageSettings.d.ts.map +1 -1
  250. package/dist/views/page-builder/PageSettings.js.map +1 -1
  251. package/dist/views/page-builder/PageTemplates.d.ts.map +1 -1
  252. package/dist/views/page-builder/PageTemplates.js.map +1 -1
  253. package/dist/views/page-builder/SEOPanel.d.ts.map +1 -1
  254. package/dist/views/page-builder/SEOPanel.js +1 -3
  255. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  256. package/dist/views/page-builder/SavedSections.d.ts.map +1 -1
  257. package/dist/views/page-builder/SavedSections.js +3 -7
  258. package/dist/views/page-builder/SavedSections.js.map +1 -1
  259. package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -1
  260. package/dist/views/page-builder/TemplatePicker.js.map +1 -1
  261. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -1
  262. package/dist/views/page-builder/block-renderers/CTAPreview.js +1 -1
  263. package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -1
  264. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -1
  265. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  266. package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -1
  267. package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -1
  268. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -5
  269. package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -1
  270. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -1
  271. package/dist/views/page-builder/block-renderers/FAQPreview.js +4 -1
  272. package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -1
  273. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -1
  274. package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -1
  275. package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -1
  276. package/dist/views/page-builder/block-renderers/FormPreview.js +2 -2
  277. package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -1
  278. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -1
  279. package/dist/views/page-builder/block-renderers/GalleryPreview.js +1 -3
  280. package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -1
  281. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -1
  282. package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -1
  283. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -1
  284. package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -1
  285. package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -1
  286. package/dist/views/page-builder/block-renderers/TextPreview.js +2 -6
  287. package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -1
  288. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -1
  289. package/dist/views/page-builder/block-renderers/VideoPreview.js +2 -5
  290. package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -1
  291. package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -1
  292. package/dist/views/page-builder/block-renderers/index.js.map +1 -1
  293. package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -1
  294. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -5
  295. package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -1
  296. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -1
  297. package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -1
  298. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -1
  299. package/dist/views/page-builder/canvas/ColumnRenderer.js +1 -5
  300. package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -1
  301. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -1
  302. package/dist/views/page-builder/canvas/ContainerRenderer.js +1 -5
  303. package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -1
  304. package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -1
  305. package/dist/views/page-builder/canvas/RowRenderer.js +1 -5
  306. package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -1
  307. package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -1
  308. package/dist/views/page-builder/canvas/SectionRenderer.js +1 -5
  309. package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -1
  310. package/dist/views/page-builder/canvas/index.d.ts.map +1 -1
  311. package/dist/views/page-builder/canvas/index.js.map +1 -1
  312. package/package.json +2 -2
  313. package/src/AdminRoot.tsx +263 -191
  314. package/src/__tests__/lib/search.test.ts +60 -69
  315. package/src/__tests__/lib/utils.test.ts +12 -12
  316. package/src/__tests__/router/match-route.test.ts +24 -26
  317. package/src/__tests__/router/strip-base.test.ts +15 -15
  318. package/src/components/Breadcrumbs.tsx +27 -24
  319. package/src/components/CommandPalette.tsx +115 -99
  320. package/src/components/ContentOverviewChart.tsx +19 -14
  321. package/src/components/ErrorBoundary.tsx +13 -13
  322. package/src/components/FocalPointPicker.tsx +31 -20
  323. package/src/components/FolderTree.tsx +172 -139
  324. package/src/components/LivePreview.tsx +68 -41
  325. package/src/components/LocaleProvider.tsx +26 -20
  326. package/src/components/LocaleSwitcher.tsx +9 -11
  327. package/src/components/MediaPickerModal.tsx +46 -45
  328. package/src/components/PresenceIndicator.tsx +30 -27
  329. package/src/components/SEOPanel.tsx +378 -228
  330. package/src/components/SEOPerformance.tsx +52 -30
  331. package/src/components/ThemeProvider.tsx +46 -46
  332. package/src/components/TipTapEditor.tsx +60 -64
  333. package/src/components/VersionHistory.tsx +63 -52
  334. package/src/components/ui/Avatar.tsx +8 -8
  335. package/src/components/ui/Badge.tsx +7 -5
  336. package/src/components/ui/Button.tsx +24 -13
  337. package/src/components/ui/CommandPalette.tsx +56 -42
  338. package/src/components/ui/ConfirmDialog.tsx +14 -14
  339. package/src/components/ui/DataTable.tsx +37 -39
  340. package/src/components/ui/EmptyState.tsx +9 -11
  341. package/src/components/ui/Modal.tsx +21 -15
  342. package/src/components/ui/Pagination.tsx +34 -19
  343. package/src/components/ui/SearchInput.tsx +17 -7
  344. package/src/components/ui/Skeleton.tsx +7 -7
  345. package/src/components/ui/Toast.tsx +29 -22
  346. package/src/components/ui/index.ts +24 -24
  347. package/src/fields/ArrayField.tsx +43 -25
  348. package/src/fields/BlockBuilderField.tsx +80 -99
  349. package/src/fields/DateField.tsx +20 -12
  350. package/src/fields/FieldRenderer.tsx +34 -34
  351. package/src/fields/GroupField.tsx +8 -10
  352. package/src/fields/MediaField.tsx +8 -10
  353. package/src/fields/NavBuilderField.tsx +24 -25
  354. package/src/fields/NumberField.tsx +21 -14
  355. package/src/fields/RelationshipField.tsx +105 -91
  356. package/src/fields/RichTextField.tsx +16 -12
  357. package/src/fields/SelectField.tsx +42 -34
  358. package/src/fields/SlugField.tsx +29 -17
  359. package/src/fields/TextField.tsx +24 -16
  360. package/src/fields/ToggleField.tsx +7 -9
  361. package/src/fields/block-types.ts +50 -24
  362. package/src/fields/index.ts +17 -17
  363. package/src/hooks/useBuilderState.ts +260 -221
  364. package/src/hooks/useContentLock.ts +23 -20
  365. package/src/hooks/useDebounce.ts +7 -7
  366. package/src/hooks/useKeyboardShortcuts.ts +16 -16
  367. package/src/index.ts +69 -58
  368. package/src/layout/Header.tsx +21 -20
  369. package/src/layout/Layout.tsx +22 -24
  370. package/src/layout/Sidebar.tsx +107 -72
  371. package/src/lib/api.ts +34 -34
  372. package/src/lib/search.ts +30 -34
  373. package/src/lib/useApiData.ts +65 -62
  374. package/src/lib/utils.ts +3 -3
  375. package/src/router/index.ts +33 -35
  376. package/src/styles/build-input.css +2 -2
  377. package/src/styles/tailwind.css +1 -1
  378. package/src/styles/theme.css +26 -2
  379. package/src/views/CollectionList.tsx +275 -121
  380. package/src/views/Dashboard.tsx +164 -117
  381. package/src/views/DocumentEdit.tsx +298 -253
  382. package/src/views/ForgotPassword.tsx +27 -23
  383. package/src/views/FormEditor.tsx +165 -99
  384. package/src/views/FormSubmissions.tsx +261 -117
  385. package/src/views/Forms.tsx +56 -26
  386. package/src/views/Login.tsx +107 -84
  387. package/src/views/MediaBrowser.tsx +717 -523
  388. package/src/views/PageEditor.tsx +44 -46
  389. package/src/views/Pages.tsx +312 -149
  390. package/src/views/PostEditor.tsx +57 -51
  391. package/src/views/Posts.tsx +206 -74
  392. package/src/views/Redirects.tsx +173 -117
  393. package/src/views/ResetPassword.tsx +43 -32
  394. package/src/views/SEO.tsx +607 -160
  395. package/src/views/ScriptTagEditor.tsx +69 -69
  396. package/src/views/ScriptTags.tsx +54 -42
  397. package/src/views/Settings.tsx +430 -220
  398. package/src/views/SetupWizard.tsx +69 -46
  399. package/src/views/Users.tsx +154 -120
  400. package/src/views/page-builder/AIBlockAssist.tsx +21 -25
  401. package/src/views/page-builder/AIGenerateDialog.tsx +134 -127
  402. package/src/views/page-builder/BlockEditor.tsx +94 -96
  403. package/src/views/page-builder/BlockPicker.tsx +73 -88
  404. package/src/views/page-builder/BottomBar.tsx +15 -11
  405. package/src/views/page-builder/BuilderToolbar.tsx +32 -29
  406. package/src/views/page-builder/ContextPanel.tsx +57 -57
  407. package/src/views/page-builder/DesignScore.tsx +52 -59
  408. package/src/views/page-builder/NodeSettings.tsx +59 -59
  409. package/src/views/page-builder/PageBuilder.tsx +156 -155
  410. package/src/views/page-builder/PageSettings.tsx +16 -15
  411. package/src/views/page-builder/PageTemplates.tsx +23 -17
  412. package/src/views/page-builder/SEOPanel.tsx +90 -111
  413. package/src/views/page-builder/SavedSections.tsx +99 -105
  414. package/src/views/page-builder/TemplatePicker.tsx +44 -48
  415. package/src/views/page-builder/block-renderers/CTAPreview.tsx +11 -13
  416. package/src/views/page-builder/block-renderers/CardsPreview.tsx +13 -15
  417. package/src/views/page-builder/block-renderers/CodePreview.tsx +16 -16
  418. package/src/views/page-builder/block-renderers/FAQPreview.tsx +20 -23
  419. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +5 -5
  420. package/src/views/page-builder/block-renderers/FormPreview.tsx +9 -13
  421. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +22 -28
  422. package/src/views/page-builder/block-renderers/HeroPreview.tsx +17 -30
  423. package/src/views/page-builder/block-renderers/ImagePreview.tsx +12 -12
  424. package/src/views/page-builder/block-renderers/TextPreview.tsx +22 -22
  425. package/src/views/page-builder/block-renderers/VideoPreview.tsx +13 -18
  426. package/src/views/page-builder/block-renderers/index.ts +17 -17
  427. package/src/views/page-builder/canvas/BlockRenderer.tsx +19 -23
  428. package/src/views/page-builder/canvas/BuilderCanvas.tsx +17 -20
  429. package/src/views/page-builder/canvas/ColumnRenderer.tsx +22 -26
  430. package/src/views/page-builder/canvas/ContainerRenderer.tsx +20 -24
  431. package/src/views/page-builder/canvas/RowRenderer.tsx +19 -23
  432. package/src/views/page-builder/canvas/SectionRenderer.tsx +30 -34
  433. package/src/views/page-builder/canvas/index.ts +2 -2
@@ -1,7 +1,7 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useCallback, useEffect, useRef, useState } from 'react';
4
- import { Command } from 'cmdk';
3
+ import { useCallback, useEffect, useRef, useState } from 'react'
4
+ import { Command } from 'cmdk'
5
5
  import {
6
6
  Search,
7
7
  FileText,
@@ -16,58 +16,60 @@ import {
16
16
  Upload,
17
17
  BarChart3,
18
18
  Clock,
19
- } from 'lucide-react';
20
- import { cmsApi } from '../lib/api.js';
19
+ } from 'lucide-react'
20
+ import { cmsApi } from '../lib/api.js'
21
21
 
22
22
  interface SearchResultDocument {
23
- id: string;
24
- title: string | null;
25
- slug: string | null;
26
- collection: string;
27
- status: string;
28
- updatedAt: string;
23
+ id: string
24
+ title: string | null
25
+ slug: string | null
26
+ collection: string
27
+ status: string
28
+ updatedAt: string
29
29
  }
30
30
 
31
31
  interface SearchResultMedia {
32
- id: string;
33
- filename: string;
34
- altText: string | null;
35
- mimeType: string;
36
- storageKey: string;
32
+ id: string
33
+ filename: string
34
+ altText: string | null
35
+ mimeType: string
36
+ storageKey: string
37
37
  }
38
38
 
39
39
  interface SearchResultUser {
40
- id: string;
41
- name: string;
42
- email: string;
43
- role: string;
40
+ id: string
41
+ name: string
42
+ email: string
43
+ role: string
44
44
  }
45
45
 
46
46
  interface RecentItem {
47
- id: string;
48
- label: string;
49
- path: string;
50
- type: 'document' | 'media' | 'user' | 'action';
47
+ id: string
48
+ label: string
49
+ path: string
50
+ type: 'document' | 'media' | 'user' | 'action'
51
51
  }
52
52
 
53
- const RECENT_ITEMS_KEY = 'actuate-recent-items';
54
- const MAX_RECENT_ITEMS = 5;
53
+ const RECENT_ITEMS_KEY = 'actuate-recent-items'
54
+ const MAX_RECENT_ITEMS = 5
55
55
 
56
56
  function loadRecentItems(): RecentItem[] {
57
57
  try {
58
- const raw = localStorage.getItem(RECENT_ITEMS_KEY);
59
- return raw ? JSON.parse(raw) : [];
58
+ const raw = localStorage.getItem(RECENT_ITEMS_KEY)
59
+ return raw ? JSON.parse(raw) : []
60
60
  } catch {
61
- return [];
61
+ return []
62
62
  }
63
63
  }
64
64
 
65
65
  function saveRecentItem(item: RecentItem): void {
66
66
  try {
67
- const items = loadRecentItems().filter((i) => i.id !== item.id);
68
- items.unshift(item);
69
- localStorage.setItem(RECENT_ITEMS_KEY, JSON.stringify(items.slice(0, MAX_RECENT_ITEMS)));
70
- } catch { /* localStorage unavailable */ }
67
+ const items = loadRecentItems().filter((i) => i.id !== item.id)
68
+ items.unshift(item)
69
+ localStorage.setItem(RECENT_ITEMS_KEY, JSON.stringify(items.slice(0, MAX_RECENT_ITEMS)))
70
+ } catch {
71
+ /* localStorage unavailable */
72
+ }
71
73
  }
72
74
 
73
75
  const staticActions = [
@@ -76,7 +78,7 @@ const staticActions = [
76
78
  { id: 'action-upload-media', label: 'Upload media', icon: Upload, action: '/media?upload=true' },
77
79
  { id: 'action-view-seo', label: 'View SEO', icon: BarChart3, action: '/seo' },
78
80
  { id: 'action-open-settings', label: 'Open settings', icon: Settings, action: '/settings' },
79
- ];
81
+ ]
80
82
 
81
83
  const navigationCommands = [
82
84
  { id: 'nav-dashboard', label: 'Dashboard', icon: LayoutDashboard, action: '/' },
@@ -87,98 +89,102 @@ const navigationCommands = [
87
89
  { id: 'nav-redirects', label: 'Redirects', icon: ArrowRightLeft, action: '/redirects' },
88
90
  { id: 'nav-users', label: 'Users', icon: Users, action: '/users' },
89
91
  { id: 'nav-settings', label: 'Settings', icon: Settings, action: '/settings' },
90
- ];
92
+ ]
91
93
 
92
94
  export interface CommandPaletteProps {
93
- open: boolean;
94
- onOpenChange: (open: boolean) => void;
95
- onNavigate: (path: string) => void;
95
+ open: boolean
96
+ onOpenChange: (open: boolean) => void
97
+ onNavigate: (path: string) => void
96
98
  }
97
99
 
98
100
  export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPaletteProps) {
99
- const [search, setSearch] = useState('');
100
- const [documents, setDocuments] = useState<SearchResultDocument[]>([]);
101
- const [media, setMedia] = useState<SearchResultMedia[]>([]);
102
- const [users, setUsers] = useState<SearchResultUser[]>([]);
103
- const [recentItems, setRecentItems] = useState<RecentItem[]>([]);
104
- const [loading, setLoading] = useState(false);
105
- const debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined);
101
+ const [search, setSearch] = useState('')
102
+ const [documents, setDocuments] = useState<SearchResultDocument[]>([])
103
+ const [media, setMedia] = useState<SearchResultMedia[]>([])
104
+ const [users, setUsers] = useState<SearchResultUser[]>([])
105
+ const [recentItems, setRecentItems] = useState<RecentItem[]>([])
106
+ const [loading, setLoading] = useState(false)
107
+ const debounceRef = useRef<ReturnType<typeof setTimeout>>(undefined)
106
108
 
107
109
  useEffect(() => {
108
110
  const down = (e: KeyboardEvent) => {
109
111
  if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
110
- e.preventDefault();
111
- onOpenChange(!open);
112
+ e.preventDefault()
113
+ onOpenChange(!open)
112
114
  }
113
- };
114
- document.addEventListener('keydown', down);
115
- return () => document.removeEventListener('keydown', down);
116
- }, [open, onOpenChange]);
115
+ }
116
+ document.addEventListener('keydown', down)
117
+ return () => document.removeEventListener('keydown', down)
118
+ }, [open, onOpenChange])
117
119
 
118
120
  useEffect(() => {
119
121
  if (open) {
120
- setRecentItems(loadRecentItems());
122
+ setRecentItems(loadRecentItems())
121
123
  }
122
- }, [open]);
124
+ }, [open])
123
125
 
124
126
  const fetchResults = useCallback(async (query: string) => {
125
127
  if (!query.trim()) {
126
- setDocuments([]);
127
- setMedia([]);
128
- setUsers([]);
129
- return;
128
+ setDocuments([])
129
+ setMedia([])
130
+ setUsers([])
131
+ return
130
132
  }
131
- setLoading(true);
133
+ setLoading(true)
132
134
  try {
133
- const res = await cmsApi<{ documents: SearchResultDocument[]; media: SearchResultMedia[]; users: SearchResultUser[] }>(
134
- `/search/global?q=${encodeURIComponent(query)}`,
135
- );
135
+ const res = await cmsApi<{
136
+ documents: SearchResultDocument[]
137
+ media: SearchResultMedia[]
138
+ users: SearchResultUser[]
139
+ }>(`/search/global?q=${encodeURIComponent(query)}`)
136
140
  if (res.data) {
137
- setDocuments(res.data.documents ?? []);
138
- setMedia(res.data.media ?? []);
139
- setUsers(res.data.users ?? []);
141
+ setDocuments(res.data.documents ?? [])
142
+ setMedia(res.data.media ?? [])
143
+ setUsers(res.data.users ?? [])
140
144
  }
141
145
  } catch {
142
- setDocuments([]);
143
- setMedia([]);
144
- setUsers([]);
146
+ setDocuments([])
147
+ setMedia([])
148
+ setUsers([])
145
149
  } finally {
146
- setLoading(false);
150
+ setLoading(false)
147
151
  }
148
- }, []);
152
+ }, [])
149
153
 
150
154
  useEffect(() => {
151
- if (debounceRef.current) clearTimeout(debounceRef.current);
155
+ if (debounceRef.current) clearTimeout(debounceRef.current)
152
156
  if (!search.trim()) {
153
- setDocuments([]);
154
- setMedia([]);
155
- setUsers([]);
156
- return;
157
+ setDocuments([])
158
+ setMedia([])
159
+ setUsers([])
160
+ return
157
161
  }
158
- debounceRef.current = setTimeout(() => fetchResults(search), 250);
159
- return () => { if (debounceRef.current) clearTimeout(debounceRef.current); };
160
- }, [search, fetchResults]);
162
+ debounceRef.current = setTimeout(() => fetchResults(search), 250)
163
+ return () => {
164
+ if (debounceRef.current) clearTimeout(debounceRef.current)
165
+ }
166
+ }, [search, fetchResults])
161
167
 
162
168
  const handleSelect = (action: string, recent?: RecentItem) => {
163
169
  if (recent) {
164
- saveRecentItem(recent);
170
+ saveRecentItem(recent)
165
171
  }
166
- onNavigate(action);
167
- onOpenChange(false);
168
- setSearch('');
169
- };
172
+ onNavigate(action)
173
+ onOpenChange(false)
174
+ setSearch('')
175
+ }
170
176
 
171
- if (!open) return null;
177
+ if (!open) return null
172
178
 
173
- const hasQuery = search.trim().length > 0;
174
- const hasResults = documents.length > 0 || media.length > 0 || users.length > 0;
179
+ const hasQuery = search.trim().length > 0
180
+ const hasResults = documents.length > 0 || media.length > 0 || users.length > 0
175
181
 
176
182
  return (
177
183
  <div
178
184
  className="fixed inset-0 z-50 bg-black/50 flex items-start justify-center pt-[20vh] px-4"
179
185
  onClick={() => {
180
- onOpenChange(false);
181
- setSearch('');
186
+ onOpenChange(false)
187
+ setSearch('')
182
188
  }}
183
189
  role="presentation"
184
190
  >
@@ -192,8 +198,8 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
192
198
  className="bg-white rounded-lg shadow-2xl w-full overflow-hidden"
193
199
  onKeyDown={(e) => {
194
200
  if (e.key === 'Escape') {
195
- onOpenChange(false);
196
- setSearch('');
201
+ onOpenChange(false)
202
+ setSearch('')
197
203
  }
198
204
  }}
199
205
  shouldFilter={!hasQuery}
@@ -257,7 +263,9 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
257
263
  <FileText className="w-4 h-4 text-gray-500" />
258
264
  <div className="flex flex-col min-w-0">
259
265
  <span className="truncate">{doc.title ?? doc.slug ?? doc.id}</span>
260
- <span className="text-xs text-gray-400">{doc.collection} &middot; {doc.status}</span>
266
+ <span className="text-xs text-gray-400">
267
+ {doc.collection} &middot; {doc.status}
268
+ </span>
261
269
  </div>
262
270
  </Command.Item>
263
271
  ))}
@@ -311,7 +319,9 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
311
319
  <Users className="w-4 h-4 text-gray-500" />
312
320
  <div className="flex flex-col min-w-0">
313
321
  <span className="truncate">{u.name}</span>
314
- <span className="text-xs text-gray-400">{u.email} &middot; {u.role}</span>
322
+ <span className="text-xs text-gray-400">
323
+ {u.email} &middot; {u.role}
324
+ </span>
315
325
  </div>
316
326
  </Command.Item>
317
327
  ))}
@@ -322,7 +332,7 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
322
332
  <Command.Group heading="Navigation" className="px-2 py-2">
323
333
  <div className="text-xs font-medium text-gray-500 mb-2">NAVIGATION</div>
324
334
  {navigationCommands.map((cmd) => {
325
- const Icon = cmd.icon;
335
+ const Icon = cmd.icon
326
336
  return (
327
337
  <Command.Item
328
338
  key={cmd.id}
@@ -333,7 +343,7 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
333
343
  <Icon className="w-4 h-4 text-gray-500" />
334
344
  <span>{cmd.label}</span>
335
345
  </Command.Item>
336
- );
346
+ )
337
347
  })}
338
348
  </Command.Group>
339
349
  )}
@@ -341,7 +351,7 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
341
351
  <Command.Group heading="Actions" className="px-2 py-2 mt-2">
342
352
  <div className="text-xs font-medium text-gray-500 mb-2">ACTIONS</div>
343
353
  {staticActions.map((cmd) => {
344
- const Icon = cmd.icon;
354
+ const Icon = cmd.icon
345
355
  return (
346
356
  <Command.Item
347
357
  key={cmd.id}
@@ -359,7 +369,7 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
359
369
  <Icon className="w-4 h-4 text-gray-500" />
360
370
  <span>{cmd.label}</span>
361
371
  </Command.Item>
362
- );
372
+ )
363
373
  })}
364
374
  </Command.Group>
365
375
  </Command.List>
@@ -367,12 +377,18 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
367
377
  <div className="border-t border-gray-200 px-4 py-3 bg-gray-50 flex items-center justify-between text-xs text-gray-500">
368
378
  <div className="flex items-center gap-4">
369
379
  <span className="flex items-center gap-1">
370
- <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">↑</kbd>
371
- <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">↓</kbd>
380
+ <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">
381
+
382
+ </kbd>
383
+ <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">
384
+
385
+ </kbd>
372
386
  to navigate
373
387
  </span>
374
388
  <span className="flex items-center gap-1">
375
- <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">↵</kbd>
389
+ <kbd className="px-1.5 py-0.5 bg-white border border-gray-300 rounded text-[10px]">
390
+
391
+ </kbd>
376
392
  to select
377
393
  </span>
378
394
  </div>
@@ -380,5 +396,5 @@ export function CommandPalette({ open, onOpenChange, onNavigate }: CommandPalett
380
396
  </Command>
381
397
  </div>
382
398
  </div>
383
- );
399
+ )
384
400
  }
@@ -1,29 +1,29 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts';
3
+ import { PieChart, Pie, Cell, ResponsiveContainer } from 'recharts'
4
4
 
5
5
  interface ContentOverviewChartProps {
6
- published: number;
7
- drafts: number;
8
- scheduled: number;
6
+ published: number
7
+ drafts: number
8
+ scheduled: number
9
9
  }
10
10
 
11
- const COLORS = ['#22c55e', '#f59e0b', '#a855f7'];
11
+ const COLORS = ['#22c55e', '#f59e0b', '#a855f7']
12
12
 
13
13
  export function ContentOverviewChart({ published, drafts, scheduled }: ContentOverviewChartProps) {
14
- const total = published + drafts + scheduled;
14
+ const total = published + drafts + scheduled
15
15
  const data = [
16
16
  { name: 'Published', value: published },
17
17
  { name: 'Drafts', value: drafts },
18
18
  { name: 'Scheduled', value: scheduled },
19
- ];
19
+ ]
20
20
 
21
21
  if (total === 0) {
22
22
  return (
23
23
  <div className="flex items-center justify-center h-full text-sm text-gray-400">
24
24
  No content yet
25
25
  </div>
26
- );
26
+ )
27
27
  }
28
28
 
29
29
  return (
@@ -50,21 +50,26 @@ export function ContentOverviewChart({ published, drafts, scheduled }: ContentOv
50
50
  </div>
51
51
  <div className="space-y-3">
52
52
  {data.map((entry, idx) => {
53
- const pct = total > 0 ? Math.round((entry.value / total) * 100) : 0;
53
+ const pct = total > 0 ? Math.round((entry.value / total) * 100) : 0
54
54
  return (
55
55
  <div key={entry.name} className="flex items-center gap-3">
56
- <span className="w-2.5 h-2.5 rounded-full shrink-0" style={{ backgroundColor: COLORS[idx] }} />
56
+ <span
57
+ className="w-2.5 h-2.5 rounded-full shrink-0"
58
+ style={{ backgroundColor: COLORS[idx] }}
59
+ />
57
60
  <div className="min-w-0">
58
61
  <span className="text-sm text-gray-700">{entry.name}</span>
59
62
  <div className="flex items-baseline gap-2">
60
- <span className="text-lg font-semibold text-gray-900">{entry.value.toLocaleString()}</span>
63
+ <span className="text-lg font-semibold text-gray-900">
64
+ {entry.value.toLocaleString()}
65
+ </span>
61
66
  <span className="text-xs text-gray-400">{pct}%</span>
62
67
  </div>
63
68
  </div>
64
69
  </div>
65
- );
70
+ )
66
71
  })}
67
72
  </div>
68
73
  </div>
69
- );
74
+ )
70
75
  }
@@ -1,34 +1,34 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { Component, type ReactNode, type ErrorInfo } from 'react';
3
+ import { Component, type ReactNode, type ErrorInfo } from 'react'
4
4
 
5
5
  interface Props {
6
- children: ReactNode;
7
- fallback?: ReactNode;
6
+ children: ReactNode
7
+ fallback?: ReactNode
8
8
  }
9
9
 
10
10
  interface State {
11
- hasError: boolean;
12
- error: Error | null;
11
+ hasError: boolean
12
+ error: Error | null
13
13
  }
14
14
 
15
15
  export class ErrorBoundary extends Component<Props, State> {
16
16
  constructor(props: Props) {
17
- super(props);
18
- this.state = { hasError: false, error: null };
17
+ super(props)
18
+ this.state = { hasError: false, error: null }
19
19
  }
20
20
 
21
21
  static getDerivedStateFromError(error: Error): State {
22
- return { hasError: true, error };
22
+ return { hasError: true, error }
23
23
  }
24
24
 
25
25
  componentDidCatch(error: Error, info: ErrorInfo) {
26
- console.error('[Actuate CMS] Unhandled error:', error, info.componentStack);
26
+ console.error('[Actuate CMS] Unhandled error:', error, info.componentStack)
27
27
  }
28
28
 
29
29
  render() {
30
30
  if (this.state.hasError) {
31
- if (this.props.fallback) return this.props.fallback;
31
+ if (this.props.fallback) return this.props.fallback
32
32
  return (
33
33
  <div className="flex min-h-[200px] items-center justify-center p-6">
34
34
  <div className="text-center">
@@ -44,9 +44,9 @@ export class ErrorBoundary extends Component<Props, State> {
44
44
  </button>
45
45
  </div>
46
46
  </div>
47
- );
47
+ )
48
48
  }
49
49
 
50
- return this.props.children;
50
+ return this.props.children
51
51
  }
52
52
  }
@@ -1,26 +1,29 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, useCallback, useRef } from 'react';
4
- import { Crosshair } from 'lucide-react';
3
+ import { useState, useCallback, useRef } from 'react'
4
+ import { Crosshair } from 'lucide-react'
5
5
 
6
6
  interface FocalPointPickerProps {
7
- imageUrl: string;
8
- focalX: number;
9
- focalY: number;
10
- onChange: (x: number, y: number) => void;
7
+ imageUrl: string
8
+ focalX: number
9
+ focalY: number
10
+ onChange: (x: number, y: number) => void
11
11
  }
12
12
 
13
13
  export function FocalPointPicker({ imageUrl, focalX, focalY, onChange }: FocalPointPickerProps) {
14
- const containerRef = useRef<HTMLDivElement>(null);
15
- const [dragging, setDragging] = useState(false);
14
+ const containerRef = useRef<HTMLDivElement>(null)
15
+ const [dragging, setDragging] = useState(false)
16
16
 
17
- const handlePosition = useCallback((e: React.MouseEvent) => {
18
- const rect = containerRef.current?.getBoundingClientRect();
19
- if (!rect) return;
20
- const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
21
- const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height));
22
- onChange(Math.round(x * 100) / 100, Math.round(y * 100) / 100);
23
- }, [onChange]);
17
+ const handlePosition = useCallback(
18
+ (e: React.MouseEvent) => {
19
+ const rect = containerRef.current?.getBoundingClientRect()
20
+ if (!rect) return
21
+ const x = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width))
22
+ const y = Math.max(0, Math.min(1, (e.clientY - rect.top) / rect.height))
23
+ onChange(Math.round(x * 100) / 100, Math.round(y * 100) / 100)
24
+ },
25
+ [onChange],
26
+ )
24
27
 
25
28
  return (
26
29
  <div className="space-y-2">
@@ -36,9 +39,16 @@ export function FocalPointPicker({ imageUrl, focalX, focalY, onChange }: FocalPo
36
39
  onMouseDown={() => setDragging(true)}
37
40
  onMouseUp={() => setDragging(false)}
38
41
  onMouseLeave={() => setDragging(false)}
39
- onMouseMove={(e) => { if (dragging) handlePosition(e); }}
42
+ onMouseMove={(e) => {
43
+ if (dragging) handlePosition(e)
44
+ }}
40
45
  >
41
- <img src={imageUrl} alt="Focal point preview" className="w-full h-full object-contain" draggable={false} />
46
+ <img
47
+ src={imageUrl}
48
+ alt="Focal point preview"
49
+ className="w-full h-full object-contain"
50
+ draggable={false}
51
+ />
42
52
  <div
43
53
  className="absolute w-6 h-6 -ml-3 -mt-3 rounded-full border-2 border-white shadow-lg bg-blue-500/50 pointer-events-none"
44
54
  style={{ left: `${focalX * 100}%`, top: `${focalY * 100}%` }}
@@ -47,8 +57,9 @@ export function FocalPointPicker({ imageUrl, focalX, focalY, onChange }: FocalPo
47
57
  </div>
48
58
  </div>
49
59
  <p className="text-xs text-[var(--muted-foreground)]">
50
- Click or drag to set the focal point ({Math.round(focalX * 100)}%, {Math.round(focalY * 100)}%)
60
+ Click or drag to set the focal point ({Math.round(focalX * 100)}%,{' '}
61
+ {Math.round(focalY * 100)}%)
51
62
  </p>
52
63
  </div>
53
- );
64
+ )
54
65
  }