@actuate-media/cms-admin 0.7.3 → 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 (435) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +95 -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.d.ts.map +1 -1
  155. package/dist/lib/api.js +33 -4
  156. package/dist/lib/api.js.map +1 -1
  157. package/dist/lib/search.d.ts.map +1 -1
  158. package/dist/lib/search.js +3 -5
  159. package/dist/lib/search.js.map +1 -1
  160. package/dist/lib/useApiData.d.ts.map +1 -1
  161. package/dist/lib/useApiData.js.map +1 -1
  162. package/dist/lib/utils.d.ts.map +1 -1
  163. package/dist/lib/utils.js.map +1 -1
  164. package/dist/router/index.d.ts.map +1 -1
  165. package/dist/router/index.js +1 -3
  166. package/dist/router/index.js.map +1 -1
  167. package/dist/views/CollectionList.d.ts.map +1 -1
  168. package/dist/views/CollectionList.js +56 -17
  169. package/dist/views/CollectionList.js.map +1 -1
  170. package/dist/views/Dashboard.d.ts.map +1 -1
  171. package/dist/views/Dashboard.js +26 -13
  172. package/dist/views/Dashboard.js.map +1 -1
  173. package/dist/views/DocumentEdit.d.ts +1 -1
  174. package/dist/views/DocumentEdit.d.ts.map +1 -1
  175. package/dist/views/DocumentEdit.js +33 -15
  176. package/dist/views/DocumentEdit.js.map +1 -1
  177. package/dist/views/ForgotPassword.d.ts.map +1 -1
  178. package/dist/views/ForgotPassword.js.map +1 -1
  179. package/dist/views/FormEditor.d.ts.map +1 -1
  180. package/dist/views/FormEditor.js +8 -2
  181. package/dist/views/FormEditor.js.map +1 -1
  182. package/dist/views/FormSubmissions.d.ts.map +1 -1
  183. package/dist/views/FormSubmissions.js +6 -6
  184. package/dist/views/FormSubmissions.js.map +1 -1
  185. package/dist/views/Forms.d.ts.map +1 -1
  186. package/dist/views/Forms.js.map +1 -1
  187. package/dist/views/Login.d.ts.map +1 -1
  188. package/dist/views/Login.js +5 -2
  189. package/dist/views/Login.js.map +1 -1
  190. package/dist/views/MediaBrowser.d.ts.map +1 -1
  191. package/dist/views/MediaBrowser.js +39 -19
  192. package/dist/views/MediaBrowser.js.map +1 -1
  193. package/dist/views/PageEditor.d.ts.map +1 -1
  194. package/dist/views/PageEditor.js.map +1 -1
  195. package/dist/views/Pages.d.ts.map +1 -1
  196. package/dist/views/Pages.js +20 -10
  197. package/dist/views/Pages.js.map +1 -1
  198. package/dist/views/PostEditor.d.ts.map +1 -1
  199. package/dist/views/PostEditor.js.map +1 -1
  200. package/dist/views/Posts.d.ts.map +1 -1
  201. package/dist/views/Posts.js +13 -7
  202. package/dist/views/Posts.js.map +1 -1
  203. package/dist/views/Redirects.d.ts.map +1 -1
  204. package/dist/views/Redirects.js +17 -5
  205. package/dist/views/Redirects.js.map +1 -1
  206. package/dist/views/ResetPassword.d.ts.map +1 -1
  207. package/dist/views/ResetPassword.js.map +1 -1
  208. package/dist/views/SEO.d.ts.map +1 -1
  209. package/dist/views/SEO.js +39 -16
  210. package/dist/views/SEO.js.map +1 -1
  211. package/dist/views/ScriptTagEditor.d.ts.map +1 -1
  212. package/dist/views/ScriptTagEditor.js +2 -1
  213. package/dist/views/ScriptTagEditor.js.map +1 -1
  214. package/dist/views/ScriptTags.d.ts.map +1 -1
  215. package/dist/views/ScriptTags.js.map +1 -1
  216. package/dist/views/Settings.d.ts.map +1 -1
  217. package/dist/views/Settings.js +38 -11
  218. package/dist/views/Settings.js.map +1 -1
  219. package/dist/views/SetupWizard.d.ts.map +1 -1
  220. package/dist/views/SetupWizard.js.map +1 -1
  221. package/dist/views/Users.d.ts.map +1 -1
  222. package/dist/views/Users.js +5 -3
  223. package/dist/views/Users.js.map +1 -1
  224. package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -1
  225. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  226. package/dist/views/page-builder/AIBlockAssist.js.map +1 -1
  227. package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -1
  228. package/dist/views/page-builder/AIGenerateDialog.js +4 -1
  229. package/dist/views/page-builder/AIGenerateDialog.js.map +1 -1
  230. package/dist/views/page-builder/BlockEditor.d.ts.map +1 -1
  231. package/dist/views/page-builder/BlockEditor.js +94 -3
  232. package/dist/views/page-builder/BlockEditor.js.map +1 -1
  233. package/dist/views/page-builder/BlockPicker.d.ts.map +1 -1
  234. package/dist/views/page-builder/BlockPicker.js.map +1 -1
  235. package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
  236. package/dist/views/page-builder/BottomBar.js.map +1 -1
  237. package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -1
  238. package/dist/views/page-builder/BuilderToolbar.js.map +1 -1
  239. package/dist/views/page-builder/ContextPanel.d.ts.map +1 -1
  240. package/dist/views/page-builder/ContextPanel.js +4 -1
  241. package/dist/views/page-builder/ContextPanel.js.map +1 -1
  242. package/dist/views/page-builder/DesignScore.d.ts.map +1 -1
  243. package/dist/views/page-builder/DesignScore.js.map +1 -1
  244. package/dist/views/page-builder/NodeSettings.d.ts.map +1 -1
  245. package/dist/views/page-builder/NodeSettings.js +1 -1
  246. package/dist/views/page-builder/NodeSettings.js.map +1 -1
  247. package/dist/views/page-builder/PageBuilder.d.ts +1 -1
  248. package/dist/views/page-builder/PageBuilder.d.ts.map +1 -1
  249. package/dist/views/page-builder/PageBuilder.js +25 -3
  250. package/dist/views/page-builder/PageBuilder.js.map +1 -1
  251. package/dist/views/page-builder/PageSettings.d.ts.map +1 -1
  252. package/dist/views/page-builder/PageSettings.js.map +1 -1
  253. package/dist/views/page-builder/PageTemplates.d.ts.map +1 -1
  254. package/dist/views/page-builder/PageTemplates.js.map +1 -1
  255. package/dist/views/page-builder/SEOPanel.d.ts.map +1 -1
  256. package/dist/views/page-builder/SEOPanel.js +1 -3
  257. package/dist/views/page-builder/SEOPanel.js.map +1 -1
  258. package/dist/views/page-builder/SavedSections.d.ts.map +1 -1
  259. package/dist/views/page-builder/SavedSections.js +3 -7
  260. package/dist/views/page-builder/SavedSections.js.map +1 -1
  261. package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -1
  262. package/dist/views/page-builder/TemplatePicker.js.map +1 -1
  263. package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -1
  264. package/dist/views/page-builder/block-renderers/CTAPreview.js +1 -1
  265. package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -1
  266. package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -1
  267. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  268. package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -1
  269. package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -1
  270. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -5
  271. package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -1
  272. package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -1
  273. package/dist/views/page-builder/block-renderers/FAQPreview.js +4 -1
  274. package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -1
  275. package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -1
  276. package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -1
  277. package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -1
  278. package/dist/views/page-builder/block-renderers/FormPreview.js +2 -2
  279. package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -1
  280. package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -1
  281. package/dist/views/page-builder/block-renderers/GalleryPreview.js +1 -3
  282. package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -1
  283. package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -1
  284. package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -1
  285. package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -1
  286. package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -1
  287. package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -1
  288. package/dist/views/page-builder/block-renderers/TextPreview.js +2 -6
  289. package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -1
  290. package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -1
  291. package/dist/views/page-builder/block-renderers/VideoPreview.js +2 -5
  292. package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -1
  293. package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -1
  294. package/dist/views/page-builder/block-renderers/index.js.map +1 -1
  295. package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -1
  296. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -5
  297. package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -1
  298. package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -1
  299. package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -1
  300. package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -1
  301. package/dist/views/page-builder/canvas/ColumnRenderer.js +1 -5
  302. package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -1
  303. package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -1
  304. package/dist/views/page-builder/canvas/ContainerRenderer.js +1 -5
  305. package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -1
  306. package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -1
  307. package/dist/views/page-builder/canvas/RowRenderer.js +1 -5
  308. package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -1
  309. package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -1
  310. package/dist/views/page-builder/canvas/SectionRenderer.js +1 -5
  311. package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -1
  312. package/dist/views/page-builder/canvas/index.d.ts.map +1 -1
  313. package/dist/views/page-builder/canvas/index.js.map +1 -1
  314. package/package.json +2 -2
  315. package/src/AdminRoot.tsx +302 -177
  316. package/src/__tests__/lib/search.test.ts +60 -69
  317. package/src/__tests__/lib/utils.test.ts +12 -12
  318. package/src/__tests__/router/match-route.test.ts +24 -26
  319. package/src/__tests__/router/strip-base.test.ts +15 -15
  320. package/src/components/Breadcrumbs.tsx +27 -24
  321. package/src/components/CommandPalette.tsx +115 -99
  322. package/src/components/ContentOverviewChart.tsx +19 -14
  323. package/src/components/ErrorBoundary.tsx +13 -13
  324. package/src/components/FocalPointPicker.tsx +31 -20
  325. package/src/components/FolderTree.tsx +172 -139
  326. package/src/components/LivePreview.tsx +68 -41
  327. package/src/components/LocaleProvider.tsx +26 -20
  328. package/src/components/LocaleSwitcher.tsx +9 -11
  329. package/src/components/MediaPickerModal.tsx +46 -45
  330. package/src/components/PresenceIndicator.tsx +30 -27
  331. package/src/components/SEOPanel.tsx +378 -228
  332. package/src/components/SEOPerformance.tsx +52 -30
  333. package/src/components/ThemeProvider.tsx +46 -46
  334. package/src/components/TipTapEditor.tsx +60 -64
  335. package/src/components/VersionHistory.tsx +63 -52
  336. package/src/components/ui/Avatar.tsx +8 -8
  337. package/src/components/ui/Badge.tsx +7 -5
  338. package/src/components/ui/Button.tsx +24 -13
  339. package/src/components/ui/CommandPalette.tsx +56 -42
  340. package/src/components/ui/ConfirmDialog.tsx +14 -14
  341. package/src/components/ui/DataTable.tsx +37 -39
  342. package/src/components/ui/EmptyState.tsx +9 -11
  343. package/src/components/ui/Modal.tsx +21 -15
  344. package/src/components/ui/Pagination.tsx +34 -19
  345. package/src/components/ui/SearchInput.tsx +17 -7
  346. package/src/components/ui/Skeleton.tsx +7 -7
  347. package/src/components/ui/Toast.tsx +29 -22
  348. package/src/components/ui/index.ts +24 -24
  349. package/src/fields/ArrayField.tsx +43 -25
  350. package/src/fields/BlockBuilderField.tsx +80 -99
  351. package/src/fields/DateField.tsx +20 -12
  352. package/src/fields/FieldRenderer.tsx +34 -34
  353. package/src/fields/GroupField.tsx +8 -10
  354. package/src/fields/MediaField.tsx +8 -10
  355. package/src/fields/NavBuilderField.tsx +24 -25
  356. package/src/fields/NumberField.tsx +21 -14
  357. package/src/fields/RelationshipField.tsx +105 -91
  358. package/src/fields/RichTextField.tsx +16 -12
  359. package/src/fields/SelectField.tsx +42 -34
  360. package/src/fields/SlugField.tsx +29 -17
  361. package/src/fields/TextField.tsx +24 -16
  362. package/src/fields/ToggleField.tsx +7 -9
  363. package/src/fields/block-types.ts +50 -24
  364. package/src/fields/index.ts +17 -17
  365. package/src/hooks/useBuilderState.ts +260 -221
  366. package/src/hooks/useContentLock.ts +23 -20
  367. package/src/hooks/useDebounce.ts +7 -7
  368. package/src/hooks/useKeyboardShortcuts.ts +16 -16
  369. package/src/index.ts +69 -58
  370. package/src/layout/Header.tsx +21 -20
  371. package/src/layout/Layout.tsx +22 -24
  372. package/src/layout/Sidebar.tsx +107 -72
  373. package/src/lib/api.ts +58 -30
  374. package/src/lib/search.ts +30 -34
  375. package/src/lib/useApiData.ts +65 -62
  376. package/src/lib/utils.ts +3 -3
  377. package/src/router/index.ts +33 -35
  378. package/src/styles/build-input.css +2 -2
  379. package/src/styles/tailwind.css +1 -1
  380. package/src/styles/theme.css +7 -1
  381. package/src/views/CollectionList.tsx +275 -121
  382. package/src/views/Dashboard.tsx +164 -117
  383. package/src/views/DocumentEdit.tsx +298 -253
  384. package/src/views/ForgotPassword.tsx +27 -23
  385. package/src/views/FormEditor.tsx +165 -99
  386. package/src/views/FormSubmissions.tsx +261 -117
  387. package/src/views/Forms.tsx +56 -26
  388. package/src/views/Login.tsx +107 -84
  389. package/src/views/MediaBrowser.tsx +717 -523
  390. package/src/views/PageEditor.tsx +44 -46
  391. package/src/views/Pages.tsx +312 -149
  392. package/src/views/PostEditor.tsx +57 -51
  393. package/src/views/Posts.tsx +206 -74
  394. package/src/views/Redirects.tsx +173 -117
  395. package/src/views/ResetPassword.tsx +43 -32
  396. package/src/views/SEO.tsx +589 -160
  397. package/src/views/ScriptTagEditor.tsx +69 -69
  398. package/src/views/ScriptTags.tsx +54 -42
  399. package/src/views/Settings.tsx +430 -220
  400. package/src/views/SetupWizard.tsx +69 -46
  401. package/src/views/Users.tsx +154 -120
  402. package/src/views/page-builder/AIBlockAssist.tsx +21 -25
  403. package/src/views/page-builder/AIGenerateDialog.tsx +134 -127
  404. package/src/views/page-builder/BlockEditor.tsx +258 -81
  405. package/src/views/page-builder/BlockPicker.tsx +73 -88
  406. package/src/views/page-builder/BottomBar.tsx +15 -11
  407. package/src/views/page-builder/BuilderToolbar.tsx +32 -29
  408. package/src/views/page-builder/ContextPanel.tsx +57 -57
  409. package/src/views/page-builder/DesignScore.tsx +52 -59
  410. package/src/views/page-builder/NodeSettings.tsx +59 -59
  411. package/src/views/page-builder/PageBuilder.tsx +164 -146
  412. package/src/views/page-builder/PageSettings.tsx +16 -15
  413. package/src/views/page-builder/PageTemplates.tsx +23 -17
  414. package/src/views/page-builder/SEOPanel.tsx +90 -111
  415. package/src/views/page-builder/SavedSections.tsx +99 -105
  416. package/src/views/page-builder/TemplatePicker.tsx +44 -48
  417. package/src/views/page-builder/block-renderers/CTAPreview.tsx +11 -13
  418. package/src/views/page-builder/block-renderers/CardsPreview.tsx +13 -15
  419. package/src/views/page-builder/block-renderers/CodePreview.tsx +16 -16
  420. package/src/views/page-builder/block-renderers/FAQPreview.tsx +20 -23
  421. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +5 -5
  422. package/src/views/page-builder/block-renderers/FormPreview.tsx +9 -13
  423. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +22 -28
  424. package/src/views/page-builder/block-renderers/HeroPreview.tsx +17 -30
  425. package/src/views/page-builder/block-renderers/ImagePreview.tsx +12 -12
  426. package/src/views/page-builder/block-renderers/TextPreview.tsx +22 -22
  427. package/src/views/page-builder/block-renderers/VideoPreview.tsx +13 -18
  428. package/src/views/page-builder/block-renderers/index.ts +17 -17
  429. package/src/views/page-builder/canvas/BlockRenderer.tsx +19 -23
  430. package/src/views/page-builder/canvas/BuilderCanvas.tsx +17 -20
  431. package/src/views/page-builder/canvas/ColumnRenderer.tsx +22 -26
  432. package/src/views/page-builder/canvas/ContainerRenderer.tsx +20 -24
  433. package/src/views/page-builder/canvas/RowRenderer.tsx +19 -23
  434. package/src/views/page-builder/canvas/SectionRenderer.tsx +30 -34
  435. package/src/views/page-builder/canvas/index.ts +2 -2
@@ -1,83 +1,102 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import * as Dialog from '@radix-ui/react-dialog';
4
- import { Pencil, Plus, Trash2, Search, ArrowUpDown, ArrowUp, ArrowDown, ArrowRightLeft, Loader2, AlertTriangle } from 'lucide-react';
5
- import { useState, useMemo, type FormEvent } from 'react';
6
- import { toast } from 'sonner';
7
- import { sortByRelevance, type SortConfig, toggleSort } from '../lib/search.js';
8
- import { useApiData } from '../lib/useApiData.js';
9
- import { cmsApi } from '../lib/api.js';
3
+ import * as Dialog from '@radix-ui/react-dialog'
4
+ import {
5
+ Pencil,
6
+ Plus,
7
+ Trash2,
8
+ Search,
9
+ ArrowUpDown,
10
+ ArrowUp,
11
+ ArrowDown,
12
+ ArrowRightLeft,
13
+ Loader2,
14
+ AlertTriangle,
15
+ } from 'lucide-react'
16
+ import { useState, useMemo, type FormEvent } from 'react'
17
+ import { toast } from 'sonner'
18
+ import { sortByRelevance, type SortConfig, toggleSort } from '../lib/search.js'
19
+ import { useApiData } from '../lib/useApiData.js'
20
+ import { cmsApi } from '../lib/api.js'
10
21
 
11
- type RedirectSortKey = 'from' | 'to' | 'type' | 'hits' | 'active';
22
+ type RedirectSortKey = 'from' | 'to' | 'type' | 'hits' | 'active'
12
23
 
13
24
  export interface RedirectsProps {
14
- onNavigate?: (path: string) => void;
25
+ onNavigate?: (path: string) => void
15
26
  }
16
27
 
17
28
  export function Redirects({ onNavigate }: RedirectsProps) {
18
- const { data, loading, error, refetch } = useApiData<any[]>('/redirects');
19
- const [showAddDialog, setShowAddDialog] = useState(false);
20
- const [newRedirect, setNewRedirect] = useState({ source: '', destination: '', type: '301' as '301' | '302' });
21
- const [searchQuery, setSearchQuery] = useState('');
22
- const [filterType, setFilterType] = useState('all');
23
- const [sortConfig, setSortConfig] = useState<SortConfig<RedirectSortKey> | null>(null);
29
+ const { data, loading, error, refetch } = useApiData<any[]>('/redirects')
30
+ const [showAddDialog, setShowAddDialog] = useState(false)
31
+ const [newRedirect, setNewRedirect] = useState({
32
+ source: '',
33
+ destination: '',
34
+ type: '301' as '301' | '302',
35
+ })
36
+ const [searchQuery, setSearchQuery] = useState('')
37
+ const [filterType, setFilterType] = useState('all')
38
+ const [sortConfig, setSortConfig] = useState<SortConfig<RedirectSortKey> | null>(null)
24
39
 
25
- const redirects = data ?? [];
40
+ const redirects = data ?? []
26
41
 
27
42
  const filteredAndSorted = useMemo(() => {
28
43
  let results = redirects.filter((r) => {
29
44
  const matchesSearch =
30
45
  (r.from ?? '').toLowerCase().includes(searchQuery.toLowerCase()) ||
31
- (r.to ?? '').toLowerCase().includes(searchQuery.toLowerCase());
32
- const matchesType = filterType === 'all' || r.type === filterType;
33
- return matchesSearch && matchesType;
34
- });
46
+ (r.to ?? '').toLowerCase().includes(searchQuery.toLowerCase())
47
+ const matchesType = filterType === 'all' || r.type === filterType
48
+ return matchesSearch && matchesType
49
+ })
35
50
 
36
51
  if (searchQuery.trim()) {
37
- results = sortByRelevance(results, searchQuery, (r) => [r.from, r.to]);
52
+ results = sortByRelevance(results, searchQuery, (r) => [r.from, r.to])
38
53
  } else if (sortConfig) {
39
54
  results = [...results].sort((a, b) => {
40
- let cmp: number;
55
+ let cmp: number
41
56
  if (sortConfig.key === 'hits') {
42
- cmp = a.hits - b.hits;
57
+ cmp = a.hits - b.hits
43
58
  } else if (sortConfig.key === 'active') {
44
- cmp = Number(a.active) - Number(b.active);
59
+ cmp = Number(a.active) - Number(b.active)
45
60
  } else {
46
- cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]));
61
+ cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]))
47
62
  }
48
- return sortConfig.direction === 'asc' ? cmp : -cmp;
49
- });
63
+ return sortConfig.direction === 'asc' ? cmp : -cmp
64
+ })
50
65
  }
51
- return results;
52
- }, [redirects, searchQuery, filterType, sortConfig]);
66
+ return results
67
+ }, [redirects, searchQuery, filterType, sortConfig])
53
68
 
54
69
  const handleSubmit = async (e: FormEvent) => {
55
- e.preventDefault();
70
+ e.preventDefault()
56
71
  const res = await cmsApi('/redirects', {
57
72
  method: 'POST',
58
- body: JSON.stringify({ from: newRedirect.source, to: newRedirect.destination, type: newRedirect.type }),
59
- });
73
+ body: JSON.stringify({
74
+ from: newRedirect.source,
75
+ to: newRedirect.destination,
76
+ type: newRedirect.type,
77
+ }),
78
+ })
60
79
  if (res.error) {
61
- toast.error(res.error);
80
+ toast.error(res.error)
62
81
  } else {
63
- toast.success('Redirect added');
64
- refetch();
82
+ toast.success('Redirect added')
83
+ refetch()
65
84
  }
66
- setShowAddDialog(false);
67
- };
85
+ setShowAddDialog(false)
86
+ }
68
87
 
69
88
  const handleDelete = async (id: number) => {
70
- const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' });
89
+ const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' })
71
90
  if (res.error) {
72
- toast.error(res.error);
91
+ toast.error(res.error)
73
92
  } else {
74
- toast.success('Redirect deleted');
75
- refetch();
93
+ toast.success('Redirect deleted')
94
+ refetch()
76
95
  }
77
- };
96
+ }
78
97
 
79
98
  function SortHeader({ label, sortKey }: { label: string; sortKey: RedirectSortKey }) {
80
- const active = sortConfig?.key === sortKey;
99
+ const active = sortConfig?.key === sortKey
81
100
  return (
82
101
  <button
83
102
  type="button"
@@ -86,12 +105,16 @@ export function Redirects({ onNavigate }: RedirectsProps) {
86
105
  >
87
106
  {label}
88
107
  {active ? (
89
- sortConfig!.direction === 'asc' ? <ArrowUp className="w-3 h-3" /> : <ArrowDown className="w-3 h-3" />
108
+ sortConfig!.direction === 'asc' ? (
109
+ <ArrowUp className="w-3 h-3" />
110
+ ) : (
111
+ <ArrowDown className="w-3 h-3" />
112
+ )
90
113
  ) : (
91
114
  <ArrowUpDown className="w-3 h-3 text-gray-400" />
92
115
  )}
93
116
  </button>
94
- );
117
+ )
95
118
  }
96
119
 
97
120
  if (loading) {
@@ -99,7 +122,7 @@ export function Redirects({ onNavigate }: RedirectsProps) {
99
122
  <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
100
123
  <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
101
124
  </div>
102
- );
125
+ )
103
126
  }
104
127
 
105
128
  return (
@@ -108,7 +131,12 @@ export function Redirects({ onNavigate }: RedirectsProps) {
108
131
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
109
132
  <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
110
133
  <span className="text-sm text-red-800 flex-1">{error}</span>
111
- <button onClick={refetch} className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors">Retry</button>
134
+ <button
135
+ onClick={refetch}
136
+ className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
137
+ >
138
+ Retry
139
+ </button>
112
140
  </div>
113
141
  )}
114
142
 
@@ -160,80 +188,102 @@ export function Redirects({ onNavigate }: RedirectsProps) {
160
188
  <p className="text-sm text-gray-500">Add your first redirect to get started.</p>
161
189
  </div>
162
190
  ) : (
163
- <div className="rounded-lg border border-gray-200 bg-white">
164
- <div className="overflow-x-auto">
165
- <table className="w-full">
166
- <thead className="border-b border-gray-200 bg-gray-50">
167
- <tr>
168
- <th className="px-4 py-2 text-left"><SortHeader label="Source URL" sortKey="from" /></th>
169
- <th className="px-4 py-2 text-left"><SortHeader label="Destination URL" sortKey="to" /></th>
170
- <th className="px-4 py-2 text-left"><SortHeader label="Type" sortKey="type" /></th>
171
- <th className="px-4 py-2 text-left"><SortHeader label="Hits" sortKey="hits" /></th>
172
- <th className="px-4 py-2 text-left"><SortHeader label="Status" sortKey="active" /></th>
173
- <th className="px-4 py-2 text-left text-xs font-medium text-gray-700">Actions</th>
174
- </tr>
175
- </thead>
176
- <tbody className="divide-y divide-gray-200">
177
- {filteredAndSorted.map((redirect) => (
178
- <tr key={redirect.id} className="transition-colors hover:bg-gray-50">
179
- <td className="px-4 py-3">
180
- <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">{redirect.from}</code>
181
- </td>
182
- <td className="px-4 py-3">
183
- <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">{redirect.to}</code>
184
- </td>
185
- <td className="px-4 py-3">
186
- <span
187
- className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
188
- redirect.type === '301' ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'
189
- }`}
190
- >
191
- {redirect.type}
192
- </span>
193
- </td>
194
- <td className="px-4 py-3 text-sm text-gray-600">{redirect.hits.toLocaleString()}</td>
195
- <td className="px-4 py-3">
196
- <span
197
- className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
198
- redirect.active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'
199
- }`}
200
- >
201
- {redirect.active ? 'Active' : 'Inactive'}
202
- </span>
203
- </td>
204
- <td className="px-4 py-3">
205
- <div className="flex items-center gap-2">
206
- <button
207
- type="button"
208
- onClick={() => onNavigate?.(`/redirects/${redirect.id}/edit`)}
209
- className="rounded p-1.5 transition-colors hover:bg-gray-100"
210
- aria-label="Edit redirect"
191
+ <div className="rounded-lg border border-gray-200 bg-white">
192
+ <div className="overflow-x-auto">
193
+ <table className="w-full">
194
+ <thead className="border-b border-gray-200 bg-gray-50">
195
+ <tr>
196
+ <th className="px-4 py-2 text-left">
197
+ <SortHeader label="Source URL" sortKey="from" />
198
+ </th>
199
+ <th className="px-4 py-2 text-left">
200
+ <SortHeader label="Destination URL" sortKey="to" />
201
+ </th>
202
+ <th className="px-4 py-2 text-left">
203
+ <SortHeader label="Type" sortKey="type" />
204
+ </th>
205
+ <th className="px-4 py-2 text-left">
206
+ <SortHeader label="Hits" sortKey="hits" />
207
+ </th>
208
+ <th className="px-4 py-2 text-left">
209
+ <SortHeader label="Status" sortKey="active" />
210
+ </th>
211
+ <th className="px-4 py-2 text-left text-xs font-medium text-gray-700">Actions</th>
212
+ </tr>
213
+ </thead>
214
+ <tbody className="divide-y divide-gray-200">
215
+ {filteredAndSorted.map((redirect) => (
216
+ <tr key={redirect.id} className="transition-colors hover:bg-gray-50">
217
+ <td className="px-4 py-3">
218
+ <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">
219
+ {redirect.from}
220
+ </code>
221
+ </td>
222
+ <td className="px-4 py-3">
223
+ <code className="rounded bg-gray-100 px-2 py-1 text-xs text-gray-900">
224
+ {redirect.to}
225
+ </code>
226
+ </td>
227
+ <td className="px-4 py-3">
228
+ <span
229
+ className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
230
+ redirect.type === '301'
231
+ ? 'bg-blue-100 text-blue-800'
232
+ : 'bg-purple-100 text-purple-800'
233
+ }`}
211
234
  >
212
- <Pencil className="h-4 w-4 text-gray-600" />
213
- </button>
214
- <button
215
- type="button"
216
- onClick={() => handleDelete(redirect.id)}
217
- className="rounded p-1.5 transition-colors hover:bg-gray-100"
218
- aria-label="Delete redirect"
235
+ {redirect.type}
236
+ </span>
237
+ </td>
238
+ <td className="px-4 py-3 text-sm text-gray-600">
239
+ {redirect.hits.toLocaleString()}
240
+ </td>
241
+ <td className="px-4 py-3">
242
+ <span
243
+ className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
244
+ redirect.active
245
+ ? 'bg-green-100 text-green-800'
246
+ : 'bg-gray-100 text-gray-800'
247
+ }`}
219
248
  >
220
- <Trash2 className="h-4 w-4 text-red-600" />
221
- </button>
222
- </div>
223
- </td>
224
- </tr>
225
- ))}
226
- </tbody>
227
- </table>
249
+ {redirect.active ? 'Active' : 'Inactive'}
250
+ </span>
251
+ </td>
252
+ <td className="px-4 py-3">
253
+ <div className="flex items-center gap-2">
254
+ <button
255
+ type="button"
256
+ onClick={() => onNavigate?.(`/redirects/${redirect.id}/edit`)}
257
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
258
+ aria-label="Edit redirect"
259
+ >
260
+ <Pencil className="h-4 w-4 text-gray-600" />
261
+ </button>
262
+ <button
263
+ type="button"
264
+ onClick={() => handleDelete(redirect.id)}
265
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
266
+ aria-label="Delete redirect"
267
+ >
268
+ <Trash2 className="h-4 w-4 text-red-600" />
269
+ </button>
270
+ </div>
271
+ </td>
272
+ </tr>
273
+ ))}
274
+ </tbody>
275
+ </table>
276
+ </div>
228
277
  </div>
229
- </div>
230
278
  )}
231
279
 
232
280
  <Dialog.Root open={showAddDialog} onOpenChange={setShowAddDialog}>
233
281
  <Dialog.Portal>
234
282
  <Dialog.Overlay className="fixed inset-0 z-50 bg-black/50" />
235
283
  <Dialog.Content className="fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg">
236
- <Dialog.Title className="mb-4 text-lg font-semibold text-gray-900">Add Redirect</Dialog.Title>
284
+ <Dialog.Title className="mb-4 text-lg font-semibold text-gray-900">
285
+ Add Redirect
286
+ </Dialog.Title>
237
287
  <form onSubmit={handleSubmit} className="space-y-4">
238
288
  <div>
239
289
  <label className="mb-1 block text-sm font-medium text-gray-700">Source URL</label>
@@ -247,7 +297,9 @@ export function Redirects({ onNavigate }: RedirectsProps) {
247
297
  />
248
298
  </div>
249
299
  <div>
250
- <label className="mb-1 block text-sm font-medium text-gray-700">Destination URL</label>
300
+ <label className="mb-1 block text-sm font-medium text-gray-700">
301
+ Destination URL
302
+ </label>
251
303
  <input
252
304
  type="text"
253
305
  value={newRedirect.destination}
@@ -258,10 +310,14 @@ export function Redirects({ onNavigate }: RedirectsProps) {
258
310
  />
259
311
  </div>
260
312
  <div>
261
- <label className="mb-1 block text-sm font-medium text-gray-700">Redirect Type</label>
313
+ <label className="mb-1 block text-sm font-medium text-gray-700">
314
+ Redirect Type
315
+ </label>
262
316
  <select
263
317
  value={newRedirect.type}
264
- onChange={(e) => setNewRedirect({ ...newRedirect, type: e.target.value as '301' | '302' })}
318
+ onChange={(e) =>
319
+ setNewRedirect({ ...newRedirect, type: e.target.value as '301' | '302' })
320
+ }
265
321
  className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500"
266
322
  >
267
323
  <option value="301">301 (Permanent)</option>
@@ -289,5 +345,5 @@ export function Redirects({ onNavigate }: RedirectsProps) {
289
345
  </Dialog.Portal>
290
346
  </Dialog.Root>
291
347
  </div>
292
- );
348
+ )
293
349
  }
@@ -1,21 +1,21 @@
1
- 'use client';
1
+ 'use client'
2
2
 
3
- import { useState, type FormEvent } from 'react';
4
- import { Shield, Eye, EyeOff, Loader2, CheckCircle2, AlertTriangle, XCircle } from 'lucide-react';
5
- import { cmsApi } from '../lib/api.js';
3
+ import { useState, type FormEvent } from 'react'
4
+ import { Shield, Eye, EyeOff, Loader2, CheckCircle2, AlertTriangle, XCircle } from 'lucide-react'
5
+ import { cmsApi } from '../lib/api.js'
6
6
 
7
7
  export interface ResetPasswordProps {
8
- onNavigate: (path: string) => void;
9
- token: string | null;
8
+ onNavigate: (path: string) => void
9
+ token: string | null
10
10
  }
11
11
 
12
12
  export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
13
- const [password, setPassword] = useState('');
14
- const [confirmPassword, setConfirmPassword] = useState('');
15
- const [showPassword, setShowPassword] = useState(false);
16
- const [submitting, setSubmitting] = useState(false);
17
- const [success, setSuccess] = useState(false);
18
- const [error, setError] = useState('');
13
+ const [password, setPassword] = useState('')
14
+ const [confirmPassword, setConfirmPassword] = useState('')
15
+ const [showPassword, setShowPassword] = useState(false)
16
+ const [submitting, setSubmitting] = useState(false)
17
+ const [success, setSuccess] = useState(false)
18
+ const [error, setError] = useState('')
19
19
 
20
20
  if (!token) {
21
21
  return (
@@ -26,7 +26,9 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
26
26
  <XCircle className="w-7 h-7 text-red-600" />
27
27
  </div>
28
28
  <h1 className="text-2xl font-bold text-gray-900">Invalid Reset Link</h1>
29
- <p className="text-gray-600 mt-2">This password reset link is invalid or has expired.</p>
29
+ <p className="text-gray-600 mt-2">
30
+ This password reset link is invalid or has expired.
31
+ </p>
30
32
  </div>
31
33
  <div className="bg-white rounded-xl border border-gray-200 p-6 shadow-sm text-center space-y-4">
32
34
  <button
@@ -46,37 +48,37 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
46
48
  </div>
47
49
  </div>
48
50
  </div>
49
- );
51
+ )
50
52
  }
51
53
 
52
- const passwordsMatch = password === confirmPassword;
53
- const meetsLength = password.length >= 8;
54
- const canSubmit = password && confirmPassword && passwordsMatch && meetsLength && !submitting;
54
+ const passwordsMatch = password === confirmPassword
55
+ const meetsLength = password.length >= 8
56
+ const canSubmit = password && confirmPassword && passwordsMatch && meetsLength && !submitting
55
57
 
56
58
  const handleSubmit = async (e: FormEvent) => {
57
- e.preventDefault();
58
- if (!canSubmit) return;
59
+ e.preventDefault()
60
+ if (!canSubmit) return
59
61
 
60
- setError('');
61
- setSubmitting(true);
62
+ setError('')
63
+ setSubmitting(true)
62
64
 
63
65
  try {
64
66
  const result = await cmsApi<{ success: boolean }>('/auth/reset-password', {
65
67
  method: 'POST',
66
68
  body: JSON.stringify({ token, password }),
67
- });
69
+ })
68
70
 
69
71
  if (result.error) {
70
- setError(result.error);
72
+ setError(result.error)
71
73
  } else {
72
- setSuccess(true);
74
+ setSuccess(true)
73
75
  }
74
76
  } catch {
75
- setError('An unexpected error occurred. Please try again.');
77
+ setError('An unexpected error occurred. Please try again.')
76
78
  } finally {
77
- setSubmitting(false);
79
+ setSubmitting(false)
78
80
  }
79
- };
81
+ }
80
82
 
81
83
  return (
82
84
  <div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
@@ -100,7 +102,8 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
100
102
  <CheckCircle2 className="w-6 h-6 text-green-600" />
101
103
  </div>
102
104
  <p className="text-sm text-gray-600">
103
- Your password has been successfully reset. All existing sessions have been revoked for security.
105
+ Your password has been successfully reset. All existing sessions have been revoked
106
+ for security.
104
107
  </p>
105
108
  <button
106
109
  type="button"
@@ -120,7 +123,10 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
120
123
  )}
121
124
 
122
125
  <div>
123
- <label htmlFor="reset-password" className="block text-sm font-medium text-gray-700 mb-1.5">
126
+ <label
127
+ htmlFor="reset-password"
128
+ className="block text-sm font-medium text-gray-700 mb-1.5"
129
+ >
124
130
  New Password
125
131
  </label>
126
132
  <div className="relative">
@@ -146,12 +152,17 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
146
152
  </button>
147
153
  </div>
148
154
  {password && !meetsLength && (
149
- <p className="mt-1 text-xs text-red-600">Password must be at least 8 characters</p>
155
+ <p className="mt-1 text-xs text-red-600">
156
+ Password must be at least 8 characters
157
+ </p>
150
158
  )}
151
159
  </div>
152
160
 
153
161
  <div>
154
- <label htmlFor="reset-confirm" className="block text-sm font-medium text-gray-700 mb-1.5">
162
+ <label
163
+ htmlFor="reset-confirm"
164
+ className="block text-sm font-medium text-gray-700 mb-1.5"
165
+ >
155
166
  Confirm Password
156
167
  </label>
157
168
  <input
@@ -188,5 +199,5 @@ export function ResetPassword({ onNavigate, token }: ResetPasswordProps) {
188
199
  </div>
189
200
  </div>
190
201
  </div>
191
- );
202
+ )
192
203
  }