@actuate-media/cms-admin 0.10.0 → 0.11.0

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 (284) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +8 -5
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/layout/primitives.test.d.ts +2 -0
  5. package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
  6. package/dist/__tests__/layout/primitives.test.js +34 -0
  7. package/dist/__tests__/layout/primitives.test.js.map +1 -0
  8. package/dist/__tests__/lib/cv.test.d.ts +2 -0
  9. package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
  10. package/dist/__tests__/lib/cv.test.js +66 -0
  11. package/dist/__tests__/lib/cv.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/assets/actuate-logo.d.ts +36 -0
  14. package/dist/assets/actuate-logo.d.ts.map +1 -0
  15. package/dist/assets/actuate-logo.js +15 -0
  16. package/dist/assets/actuate-logo.js.map +1 -0
  17. package/dist/components/Breadcrumbs.js +2 -2
  18. package/dist/components/CommandPalette.js +10 -10
  19. package/dist/components/ContentOverviewChart.js +3 -3
  20. package/dist/components/ErrorBoundary.js +1 -1
  21. package/dist/components/FocalPointPicker.js +2 -2
  22. package/dist/components/FolderTree.js +20 -20
  23. package/dist/components/LivePreview.js +3 -3
  24. package/dist/components/LocaleSwitcher.js +1 -1
  25. package/dist/components/MediaPickerModal.js +4 -4
  26. package/dist/components/PresenceIndicator.js +1 -1
  27. package/dist/components/SEOConfigPanel.d.ts +2 -0
  28. package/dist/components/SEOConfigPanel.d.ts.map +1 -0
  29. package/dist/components/SEOConfigPanel.js +174 -0
  30. package/dist/components/SEOConfigPanel.js.map +1 -0
  31. package/dist/components/SEOPanel.js +9 -9
  32. package/dist/components/SEOPerformance.js +2 -2
  33. package/dist/components/SchedulePublishDialog.js +1 -1
  34. package/dist/components/SharePreviewLinkDialog.js +1 -1
  35. package/dist/components/TipTapEditor.js +5 -5
  36. package/dist/components/VersionHistory.js +2 -2
  37. package/dist/components/ui/Badge.d.ts +33 -3
  38. package/dist/components/ui/Badge.d.ts.map +1 -1
  39. package/dist/components/ui/Badge.js +42 -8
  40. package/dist/components/ui/Badge.js.map +1 -1
  41. package/dist/components/ui/Button.d.ts +19 -8
  42. package/dist/components/ui/Button.d.ts.map +1 -1
  43. package/dist/components/ui/Button.js +35 -14
  44. package/dist/components/ui/Button.js.map +1 -1
  45. package/dist/components/ui/Card.d.ts +26 -0
  46. package/dist/components/ui/Card.d.ts.map +1 -0
  47. package/dist/components/ui/Card.js +45 -0
  48. package/dist/components/ui/Card.js.map +1 -0
  49. package/dist/components/ui/DataTable.js +1 -1
  50. package/dist/components/ui/Input.d.ts +15 -0
  51. package/dist/components/ui/Input.d.ts.map +1 -0
  52. package/dist/components/ui/Input.js +23 -0
  53. package/dist/components/ui/Input.js.map +1 -0
  54. package/dist/components/ui/SearchInput.js +1 -1
  55. package/dist/components/ui/Select.d.ts +16 -0
  56. package/dist/components/ui/Select.d.ts.map +1 -0
  57. package/dist/components/ui/Select.js +25 -0
  58. package/dist/components/ui/Select.js.map +1 -0
  59. package/dist/components/ui/Toast.js +1 -1
  60. package/dist/components/ui/index.d.ts +10 -4
  61. package/dist/components/ui/index.d.ts.map +1 -1
  62. package/dist/components/ui/index.js +5 -2
  63. package/dist/components/ui/index.js.map +1 -1
  64. package/dist/fields/BlockBuilderField.js +3 -3
  65. package/dist/fields/DateField.js +1 -1
  66. package/dist/fields/RelationshipField.js +3 -3
  67. package/dist/fields/TextField.js +1 -1
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +3 -0
  71. package/dist/index.js.map +1 -1
  72. package/dist/layout/Header.js +1 -1
  73. package/dist/layout/Layout.d.ts +14 -0
  74. package/dist/layout/Layout.d.ts.map +1 -1
  75. package/dist/layout/Layout.js +17 -11
  76. package/dist/layout/Layout.js.map +1 -1
  77. package/dist/layout/Sidebar.d.ts.map +1 -1
  78. package/dist/layout/Sidebar.js +21 -11
  79. package/dist/layout/Sidebar.js.map +1 -1
  80. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  81. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  82. package/dist/layout/primitives/AdminShell.js +51 -0
  83. package/dist/layout/primitives/AdminShell.js.map +1 -0
  84. package/dist/layout/primitives/Box.d.ts +19 -0
  85. package/dist/layout/primitives/Box.d.ts.map +1 -0
  86. package/dist/layout/primitives/Box.js +12 -0
  87. package/dist/layout/primitives/Box.js.map +1 -0
  88. package/dist/layout/primitives/Cluster.d.ts +27 -0
  89. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  90. package/dist/layout/primitives/Cluster.js +37 -0
  91. package/dist/layout/primitives/Cluster.js.map +1 -0
  92. package/dist/layout/primitives/Grid.d.ts +45 -0
  93. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  94. package/dist/layout/primitives/Grid.js +59 -0
  95. package/dist/layout/primitives/Grid.js.map +1 -0
  96. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  97. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  98. package/dist/layout/primitives/PageContainer.js +41 -0
  99. package/dist/layout/primitives/PageContainer.js.map +1 -0
  100. package/dist/layout/primitives/Split.d.ts +34 -0
  101. package/dist/layout/primitives/Split.d.ts.map +1 -0
  102. package/dist/layout/primitives/Split.js +27 -0
  103. package/dist/layout/primitives/Split.js.map +1 -0
  104. package/dist/layout/primitives/Stack.d.ts +23 -0
  105. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  106. package/dist/layout/primitives/Stack.js +34 -0
  107. package/dist/layout/primitives/Stack.js.map +1 -0
  108. package/dist/layout/primitives/index.d.ts +30 -0
  109. package/dist/layout/primitives/index.d.ts.map +1 -0
  110. package/dist/layout/primitives/index.js +22 -0
  111. package/dist/layout/primitives/index.js.map +1 -0
  112. package/dist/layout/primitives/tokens.d.ts +48 -0
  113. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  114. package/dist/layout/primitives/tokens.js +54 -0
  115. package/dist/layout/primitives/tokens.js.map +1 -0
  116. package/dist/lib/cv.d.ts +53 -0
  117. package/dist/lib/cv.d.ts.map +1 -0
  118. package/dist/lib/cv.js +39 -0
  119. package/dist/lib/cv.js.map +1 -0
  120. package/dist/views/ApiKeys.js +7 -7
  121. package/dist/views/CollectionList.js +8 -8
  122. package/dist/views/Dashboard.d.ts.map +1 -1
  123. package/dist/views/Dashboard.js +333 -78
  124. package/dist/views/Dashboard.js.map +1 -1
  125. package/dist/views/DocumentEdit.js +3 -3
  126. package/dist/views/ForgotPassword.js +2 -2
  127. package/dist/views/FormEditor.js +5 -5
  128. package/dist/views/FormSubmissions.js +6 -6
  129. package/dist/views/Forms.js +2 -2
  130. package/dist/views/Login.d.ts +16 -1
  131. package/dist/views/Login.d.ts.map +1 -1
  132. package/dist/views/Login.js +17 -7
  133. package/dist/views/Login.js.map +1 -1
  134. package/dist/views/MediaBrowser.js +16 -16
  135. package/dist/views/PageEditor.js +2 -2
  136. package/dist/views/Pages.js +10 -10
  137. package/dist/views/PostEditor.js +2 -2
  138. package/dist/views/Posts.js +4 -4
  139. package/dist/views/Redirects.js +4 -4
  140. package/dist/views/ResetPassword.js +2 -2
  141. package/dist/views/SEO.js +6 -6
  142. package/dist/views/ScriptTagEditor.js +4 -4
  143. package/dist/views/ScriptTags.js +2 -2
  144. package/dist/views/Settings.d.ts.map +1 -1
  145. package/dist/views/Settings.js +9 -8
  146. package/dist/views/Settings.js.map +1 -1
  147. package/dist/views/SetupWizard.js +2 -2
  148. package/dist/views/Users.js +4 -4
  149. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  150. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  151. package/dist/views/page-builder/BlockEditor.js +10 -10
  152. package/dist/views/page-builder/BlockPicker.js +4 -4
  153. package/dist/views/page-builder/BottomBar.js +1 -1
  154. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  155. package/dist/views/page-builder/ContextPanel.js +2 -2
  156. package/dist/views/page-builder/DesignScore.js +9 -9
  157. package/dist/views/page-builder/NodeSettings.js +8 -8
  158. package/dist/views/page-builder/PageBuilder.js +3 -3
  159. package/dist/views/page-builder/PageSettings.js +1 -1
  160. package/dist/views/page-builder/PageTemplates.js +2 -2
  161. package/dist/views/page-builder/SEOPanel.js +13 -13
  162. package/dist/views/page-builder/SavedSections.js +5 -5
  163. package/dist/views/page-builder/TemplatePicker.js +2 -2
  164. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  165. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  166. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  167. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  168. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  169. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  170. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  171. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  172. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  173. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  174. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  175. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  176. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  177. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  178. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  179. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  180. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  181. package/package.json +6 -2
  182. package/src/AdminRoot.tsx +21 -11
  183. package/src/__tests__/layout/primitives.test.ts +37 -0
  184. package/src/__tests__/lib/cv.test.ts +74 -0
  185. package/src/assets/actuate-logo.tsx +72 -0
  186. package/src/components/Breadcrumbs.tsx +6 -6
  187. package/src/components/CommandPalette.tsx +34 -34
  188. package/src/components/ContentOverviewChart.tsx +3 -3
  189. package/src/components/ErrorBoundary.tsx +3 -3
  190. package/src/components/FocalPointPicker.tsx +4 -4
  191. package/src/components/FolderTree.tsx +38 -38
  192. package/src/components/LivePreview.tsx +16 -16
  193. package/src/components/LocaleSwitcher.tsx +7 -7
  194. package/src/components/MediaPickerModal.tsx +21 -21
  195. package/src/components/PresenceIndicator.tsx +2 -2
  196. package/src/components/SEOConfigPanel.tsx +582 -0
  197. package/src/components/SEOPanel.tsx +46 -46
  198. package/src/components/SEOPerformance.tsx +21 -21
  199. package/src/components/SchedulePublishDialog.tsx +4 -4
  200. package/src/components/SharePreviewLinkDialog.tsx +1 -1
  201. package/src/components/TipTapEditor.tsx +33 -33
  202. package/src/components/VersionHistory.tsx +16 -16
  203. package/src/components/ui/Badge.tsx +66 -14
  204. package/src/components/ui/Button.tsx +70 -33
  205. package/src/components/ui/Card.tsx +101 -0
  206. package/src/components/ui/DataTable.tsx +1 -1
  207. package/src/components/ui/Input.tsx +35 -0
  208. package/src/components/ui/SearchInput.tsx +4 -4
  209. package/src/components/ui/Select.tsx +56 -0
  210. package/src/components/ui/Toast.tsx +1 -1
  211. package/src/components/ui/index.ts +18 -4
  212. package/src/fields/BlockBuilderField.tsx +3 -3
  213. package/src/fields/DateField.tsx +1 -1
  214. package/src/fields/RelationshipField.tsx +10 -10
  215. package/src/fields/TextField.tsx +1 -1
  216. package/src/index.ts +28 -0
  217. package/src/layout/Header.tsx +28 -28
  218. package/src/layout/Layout.tsx +39 -46
  219. package/src/layout/Sidebar.tsx +37 -64
  220. package/src/layout/primitives/AdminShell.tsx +118 -0
  221. package/src/layout/primitives/Box.tsx +30 -0
  222. package/src/layout/primitives/Cluster.tsx +74 -0
  223. package/src/layout/primitives/Grid.tsx +120 -0
  224. package/src/layout/primitives/PageContainer.tsx +96 -0
  225. package/src/layout/primitives/Split.tsx +73 -0
  226. package/src/layout/primitives/Stack.tsx +67 -0
  227. package/src/layout/primitives/index.ts +36 -0
  228. package/src/layout/primitives/tokens.ts +76 -0
  229. package/src/lib/cv.ts +96 -0
  230. package/src/styles/build-input.css +1 -1
  231. package/src/views/ApiKeys.tsx +57 -57
  232. package/src/views/CollectionList.tsx +30 -30
  233. package/src/views/Dashboard.tsx +737 -186
  234. package/src/views/DocumentEdit.tsx +9 -9
  235. package/src/views/ForgotPassword.tsx +18 -18
  236. package/src/views/FormEditor.tsx +75 -75
  237. package/src/views/FormSubmissions.tsx +76 -76
  238. package/src/views/Forms.tsx +27 -27
  239. package/src/views/Login.tsx +65 -25
  240. package/src/views/MediaBrowser.tsx +127 -127
  241. package/src/views/PageEditor.tsx +25 -25
  242. package/src/views/Pages.tsx +59 -59
  243. package/src/views/PostEditor.tsx +37 -37
  244. package/src/views/Posts.tsx +48 -48
  245. package/src/views/Redirects.tsx +21 -21
  246. package/src/views/ResetPassword.tsx +28 -28
  247. package/src/views/SEO.tsx +144 -144
  248. package/src/views/ScriptTagEditor.tsx +24 -24
  249. package/src/views/ScriptTags.tsx +10 -10
  250. package/src/views/Settings.tsx +88 -80
  251. package/src/views/SetupWizard.tsx +28 -28
  252. package/src/views/Users.tsx +20 -20
  253. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  254. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  255. package/src/views/page-builder/BlockEditor.tsx +26 -26
  256. package/src/views/page-builder/BlockPicker.tsx +22 -22
  257. package/src/views/page-builder/BottomBar.tsx +8 -8
  258. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  259. package/src/views/page-builder/ContextPanel.tsx +3 -3
  260. package/src/views/page-builder/DesignScore.tsx +21 -21
  261. package/src/views/page-builder/NodeSettings.tsx +27 -27
  262. package/src/views/page-builder/PageBuilder.tsx +11 -11
  263. package/src/views/page-builder/PageSettings.tsx +4 -4
  264. package/src/views/page-builder/PageTemplates.tsx +18 -18
  265. package/src/views/page-builder/SEOPanel.tsx +53 -53
  266. package/src/views/page-builder/SavedSections.tsx +37 -37
  267. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  268. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  269. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  270. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  271. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  272. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  273. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  274. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  275. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  276. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  277. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  278. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  279. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  280. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  281. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  282. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  283. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  284. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -81,18 +81,18 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
81
81
 
82
82
  if (!isNew && loading) {
83
83
  return (
84
- <div className="h-full flex items-center justify-center">
85
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
84
+ <div className="flex h-full items-center justify-center">
85
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
86
86
  </div>
87
87
  )
88
88
  }
89
89
 
90
90
  return (
91
- <div className="h-full flex flex-col bg-white">
91
+ <div className="flex h-full flex-col bg-white">
92
92
  {error && (
93
93
  <div className="mx-4 mt-3 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
94
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
95
- <span className="text-sm text-red-800 flex-1">{error}</span>
94
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
95
+ <span className="flex-1 text-sm text-red-800">{error}</span>
96
96
  </div>
97
97
  )}
98
98
 
@@ -100,63 +100,63 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
100
100
  <div className="flex items-center justify-between">
101
101
  <button
102
102
  onClick={() => onNavigate?.('/pages')}
103
- className="inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 transition-colors"
103
+ className="inline-flex items-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-900"
104
104
  >
105
- <ArrowLeft className="w-4 h-4" />
105
+ <ArrowLeft className="h-4 w-4" />
106
106
  Back to Pages
107
107
  </button>
108
108
  <div className="flex items-center gap-3">
109
- <button className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg flex items-center gap-2 hover:bg-gray-50 transition-colors">
110
- <Eye className="w-4 h-4" />
109
+ <button className="flex items-center gap-2 rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50">
110
+ <Eye className="h-4 w-4" />
111
111
  Preview
112
112
  </button>
113
113
  </div>
114
114
  </div>
115
115
  </div>
116
116
 
117
- <div className="flex-1 overflow-hidden flex">
117
+ <div className="flex flex-1 overflow-hidden">
118
118
  <div className="flex-1 overflow-y-auto">
119
- <div className="max-w-4xl mx-auto p-3 pr-6 sm:p-4 sm:pr-8">
119
+ <div className="mx-auto max-w-4xl p-3 pr-6 sm:p-4 sm:pr-8">
120
120
  <input
121
121
  type="text"
122
122
  value={title}
123
123
  onChange={(e) => setTitle(e.target.value)}
124
124
  placeholder="Page title"
125
- className="w-full text-2xl sm:text-3xl font-bold mb-4 px-0 border-none focus:outline-none focus:ring-0 placeholder:text-gray-300"
125
+ className="mb-4 w-full border-none px-0 text-2xl font-bold placeholder:text-gray-300 focus:ring-0 focus:outline-none sm:text-3xl"
126
126
  />
127
127
 
128
128
  <div className="mb-4">
129
- <label className="block text-xs font-medium text-gray-600 mb-1">URL Slug</label>
129
+ <label className="mb-1 block text-xs font-medium text-gray-600">URL Slug</label>
130
130
  <input
131
131
  type="text"
132
132
  value={slug}
133
133
  onChange={(e) => setSlug(e.target.value)}
134
134
  placeholder="url-slug"
135
- className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
135
+ className="w-full rounded-lg border border-gray-300 px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
136
136
  />
137
137
  </div>
138
138
 
139
- <div className="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center">
140
- <p className="text-gray-500 mb-2">No blocks added yet</p>
139
+ <div className="rounded-lg border-2 border-dashed border-gray-300 p-8 text-center">
140
+ <p className="mb-2 text-gray-500">No blocks added yet</p>
141
141
  <p className="text-sm text-gray-400">Click "Add Block" to start building your page</p>
142
- <button className="mt-4 px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
142
+ <button className="mt-4 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700">
143
143
  Add Block
144
144
  </button>
145
145
  </div>
146
146
  </div>
147
147
  </div>
148
148
 
149
- <div className="w-[30%] border-l border-gray-200 overflow-y-auto bg-gray-50">
150
- <div className="p-4 space-y-4">
151
- <div className="bg-white rounded-lg border border-gray-200 p-4">
152
- <h3 className="font-semibold text-gray-900 mb-3 text-sm">Publish</h3>
149
+ <div className="w-[30%] overflow-y-auto border-l border-gray-200 bg-gray-50">
150
+ <div className="space-y-4 p-4">
151
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
152
+ <h3 className="mb-3 text-sm font-semibold text-gray-900">Publish</h3>
153
153
  <div className="space-y-3">
154
154
  <div>
155
- <label className="block text-xs font-medium text-gray-700 mb-1">Status</label>
155
+ <label className="mb-1 block text-xs font-medium text-gray-700">Status</label>
156
156
  <select
157
157
  value={status}
158
158
  onChange={(e) => setStatus(e.target.value as 'draft' | 'published')}
159
- className="w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
159
+ className="w-full rounded-lg border border-gray-300 px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
160
160
  >
161
161
  <option value="draft">Draft</option>
162
162
  <option value="published">Published</option>
@@ -165,7 +165,7 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
165
165
  <button
166
166
  onClick={savePage}
167
167
  disabled={saving}
168
- className="w-full py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium disabled:opacity-50"
168
+ className="w-full rounded-lg bg-blue-600 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700 disabled:opacity-50"
169
169
  >
170
170
  {saving ? 'Saving...' : 'Save Page'}
171
171
  </button>
@@ -173,7 +173,7 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
173
173
  <button
174
174
  onClick={publishPage}
175
175
  disabled={saving}
176
- className="w-full py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium disabled:opacity-50"
176
+ className="w-full rounded-lg bg-green-600 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700 disabled:opacity-50"
177
177
  >
178
178
  {saving ? 'Publishing...' : 'Publish'}
179
179
  </button>
@@ -73,7 +73,7 @@ function SeoScoreBadge({ score }: { score: number }) {
73
73
  const color = score >= 80 ? 'bg-green-500' : score >= 60 ? 'bg-amber-500' : 'bg-red-500'
74
74
  return (
75
75
  <div className="flex items-center gap-1.5">
76
- <span className={`w-2.5 h-2.5 rounded-full ${color}`} />
76
+ <span className={`h-2.5 w-2.5 rounded-full ${color}`} />
77
77
  <span className="text-xs text-gray-600">{score}</span>
78
78
  </div>
79
79
  )
@@ -83,7 +83,7 @@ function FolderBadge({ name }: { name: string }) {
83
83
  const colors = getFolderColor(name)
84
84
  return (
85
85
  <span
86
- className={`inline-flex px-2 py-0.5 rounded text-xs font-medium ${colors.bg} ${colors.text}`}
86
+ className={`inline-flex rounded px-2 py-0.5 text-xs font-medium ${colors.bg} ${colors.text}`}
87
87
  >
88
88
  {name}
89
89
  </span>
@@ -229,17 +229,17 @@ export function Pages({ onNavigate }: PagesProps) {
229
229
  <button
230
230
  type="button"
231
231
  onClick={() => setSortConfig(toggleSort(sortConfig, sortKey))}
232
- className="flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900 transition-colors"
232
+ className="flex items-center gap-1 text-xs font-medium text-gray-700 transition-colors hover:text-gray-900"
233
233
  >
234
234
  {label}
235
235
  {active ? (
236
236
  sortConfig!.direction === 'asc' ? (
237
- <ArrowUp className="w-3 h-3" />
237
+ <ArrowUp className="h-3 w-3" />
238
238
  ) : (
239
- <ArrowDown className="w-3 h-3" />
239
+ <ArrowDown className="h-3 w-3" />
240
240
  )
241
241
  ) : (
242
- <ArrowUpDown className="w-3 h-3 text-gray-400" />
242
+ <ArrowUpDown className="h-3 w-3 text-gray-400" />
243
243
  )}
244
244
  </button>
245
245
  )
@@ -247,39 +247,39 @@ export function Pages({ onNavigate }: PagesProps) {
247
247
 
248
248
  if (loading) {
249
249
  return (
250
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
251
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
250
+ <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
251
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
252
252
  </div>
253
253
  )
254
254
  }
255
255
 
256
256
  return (
257
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 h-full flex flex-col">
257
+ <div className="flex h-full flex-col p-3 pr-6 sm:p-4 sm:pr-8">
258
258
  {error && (
259
259
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
260
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
261
- <span className="text-sm text-red-800 flex-1">{error}</span>
260
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
261
+ <span className="flex-1 text-sm text-red-800">{error}</span>
262
262
  <button
263
263
  onClick={refetch}
264
- className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
264
+ className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
265
265
  >
266
266
  Retry
267
267
  </button>
268
268
  </div>
269
269
  )}
270
270
 
271
- <div className="flex flex-col sm:flex-row sm:items-center justify-between mb-4 gap-3">
271
+ <div className="mb-4 flex flex-col justify-between gap-3 sm:flex-row sm:items-center">
272
272
  <div className="flex items-center gap-3">
273
273
  <button
274
274
  type="button"
275
275
  onClick={() => setSidebarOpen((prev) => !prev)}
276
- className="p-1.5 rounded-lg hover:bg-gray-100 transition-colors"
276
+ className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
277
277
  title={sidebarOpen ? 'Hide folders' : 'Show folders'}
278
278
  >
279
- <FolderInput className="w-5 h-5 text-gray-600" />
279
+ <FolderInput className="h-5 w-5 text-gray-600" />
280
280
  </button>
281
281
  <div>
282
- <h1 className="text-xl sm:text-2xl font-semibold text-gray-900">Pages</h1>
282
+ <h1 className="text-xl font-semibold text-gray-900 sm:text-2xl">Pages</h1>
283
283
  <p className="text-sm text-gray-500">
284
284
  {totalCount} page{totalCount !== 1 ? 's' : ''}
285
285
  </p>
@@ -287,17 +287,17 @@ export function Pages({ onNavigate }: PagesProps) {
287
287
  </div>
288
288
  <button
289
289
  onClick={() => onNavigate?.('/pages/new')}
290
- className="flex items-center justify-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm"
290
+ className="flex items-center justify-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
291
291
  >
292
- <Plus className="w-4 h-4" />
292
+ <Plus className="h-4 w-4" />
293
293
  <span className="hidden sm:inline">New Page</span>
294
294
  <span className="sm:hidden">New</span>
295
295
  </button>
296
296
  </div>
297
297
 
298
- <div className="flex gap-4 flex-1 min-h-0 overflow-hidden">
298
+ <div className="flex min-h-0 flex-1 gap-4 overflow-hidden">
299
299
  {sidebarOpen && (
300
- <div className="w-56 shrink-0 bg-white rounded-lg border border-gray-200 overflow-hidden flex flex-col">
300
+ <div className="flex w-56 shrink-0 flex-col overflow-hidden rounded-lg border border-gray-200 bg-white">
301
301
  <FolderTree
302
302
  scope="pages"
303
303
  selected={folderSel}
@@ -312,24 +312,24 @@ export function Pages({ onNavigate }: PagesProps) {
312
312
  </div>
313
313
  )}
314
314
 
315
- <div className="flex-1 flex flex-col min-w-0">
316
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
317
- <div className="p-3 flex flex-col gap-3">
315
+ <div className="flex min-w-0 flex-1 flex-col">
316
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
317
+ <div className="flex flex-col gap-3 p-3">
318
318
  <div className="relative">
319
- <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
319
+ <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
320
320
  <input
321
321
  type="text"
322
322
  placeholder="Search pages..."
323
323
  value={searchQuery}
324
324
  onChange={(e) => setSearchQuery(e.target.value)}
325
- className="w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
325
+ className="w-full rounded-lg border border-gray-300 py-2 pr-3 pl-9 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
326
326
  />
327
327
  </div>
328
- <div className="flex flex-col sm:flex-row gap-2">
328
+ <div className="flex flex-col gap-2 sm:flex-row">
329
329
  <select
330
330
  value={filterStatus}
331
331
  onChange={(e) => setFilterStatus(e.target.value)}
332
- className="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
332
+ className="flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
333
333
  >
334
334
  <option value="all">All Status</option>
335
335
  <option value="published">Published</option>
@@ -338,7 +338,7 @@ export function Pages({ onNavigate }: PagesProps) {
338
338
  <select
339
339
  value={filterTemplate}
340
340
  onChange={(e) => setFilterTemplate(e.target.value)}
341
- className="flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
341
+ className="flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
342
342
  >
343
343
  <option value="all">All Templates</option>
344
344
  <option value="landing">Landing</option>
@@ -348,9 +348,9 @@ export function Pages({ onNavigate }: PagesProps) {
348
348
  </select>
349
349
  <button
350
350
  type="button"
351
- className="flex items-center justify-center gap-2 px-3 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
351
+ className="flex items-center justify-center gap-2 rounded-lg border border-gray-300 px-3 py-2 text-sm transition-colors hover:bg-gray-50"
352
352
  >
353
- <SlidersHorizontal className="w-4 h-4" />
353
+ <SlidersHorizontal className="h-4 w-4" />
354
354
  <span className="hidden sm:inline">More Filters</span>
355
355
  </button>
356
356
  </div>
@@ -358,8 +358,8 @@ export function Pages({ onNavigate }: PagesProps) {
358
358
  </div>
359
359
 
360
360
  {selectedPages.length > 0 && (
361
- <div className="bg-blue-50 border border-blue-200 rounded-lg p-3 mb-4">
362
- <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-2">
361
+ <div className="mb-4 rounded-lg border border-blue-200 bg-blue-50 p-3">
362
+ <div className="flex flex-col justify-between gap-2 sm:flex-row sm:items-center">
363
363
  <span className="text-sm text-blue-900">
364
364
  {selectedPages.length} page{selectedPages.length !== 1 ? 's' : ''} selected
365
365
  </span>
@@ -367,28 +367,28 @@ export function Pages({ onNavigate }: PagesProps) {
367
367
  <button
368
368
  type="button"
369
369
  onClick={handleBulkPublish}
370
- className="flex-1 sm:flex-none px-3 py-1.5 text-sm bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
370
+ className="flex-1 rounded-lg bg-green-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-green-700 sm:flex-none"
371
371
  >
372
372
  Publish
373
373
  </button>
374
374
  <button
375
375
  type="button"
376
376
  onClick={handleBulkUnpublish}
377
- className="flex-1 sm:flex-none px-3 py-1.5 text-sm bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 transition-colors"
377
+ className="flex-1 rounded-lg bg-yellow-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-yellow-700 sm:flex-none"
378
378
  >
379
379
  Unpublish
380
380
  </button>
381
381
  <button
382
382
  type="button"
383
383
  onClick={handleBulkDelete}
384
- className="flex-1 sm:flex-none px-3 py-1.5 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
384
+ className="flex-1 rounded-lg bg-red-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-red-700 sm:flex-none"
385
385
  >
386
386
  Delete
387
387
  </button>
388
388
  <button
389
389
  type="button"
390
390
  onClick={() => setSelectedPages([])}
391
- className="flex-1 sm:flex-none px-3 py-1.5 text-sm border border-gray-300 bg-white rounded-lg hover:bg-gray-50 transition-colors"
391
+ className="flex-1 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm transition-colors hover:bg-gray-50 sm:flex-none"
392
392
  >
393
393
  Cancel
394
394
  </button>
@@ -398,8 +398,8 @@ export function Pages({ onNavigate }: PagesProps) {
398
398
  )}
399
399
 
400
400
  {filteredAndSorted.length === 0 && !error ? (
401
- <div className="bg-white rounded-lg border border-gray-200 p-8 text-center flex-1 flex flex-col items-center justify-center">
402
- <p className="text-sm text-gray-500 mb-2">
401
+ <div className="flex flex-1 flex-col items-center justify-center rounded-lg border border-gray-200 bg-white p-8 text-center">
402
+ <p className="mb-2 text-sm text-gray-500">
403
403
  {folderSel.type === 'smart' && folderSel.smart === 'uncategorized'
404
404
  ? 'No uncategorized pages'
405
405
  : folderSel.type === 'folder'
@@ -408,17 +408,17 @@ export function Pages({ onNavigate }: PagesProps) {
408
408
  </p>
409
409
  <button
410
410
  onClick={() => onNavigate?.('/pages/new')}
411
- className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
411
+ className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
412
412
  >
413
413
  Create your first page
414
414
  </button>
415
415
  </div>
416
416
  ) : (
417
417
  <>
418
- <div className="hidden md:block bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden">
419
- <div className="overflow-x-auto h-full">
418
+ <div className="hidden flex-1 overflow-hidden rounded-lg border border-gray-200 bg-white md:block">
419
+ <div className="h-full overflow-x-auto">
420
420
  <table className="w-full">
421
- <thead className="bg-gray-50 border-b border-gray-200 sticky top-0">
421
+ <thead className="sticky top-0 border-b border-gray-200 bg-gray-50">
422
422
  <tr>
423
423
  <th className="w-8 px-3 py-2 text-left">
424
424
  <input
@@ -462,7 +462,7 @@ export function Pages({ onNavigate }: PagesProps) {
462
462
  return (
463
463
  <tr
464
464
  key={page.id}
465
- className="hover:bg-gray-50 transition-colors"
465
+ className="transition-colors hover:bg-gray-50"
466
466
  draggable
467
467
  onDragStart={(e) => handleDragStart(e, page.id)}
468
468
  >
@@ -474,14 +474,14 @@ export function Pages({ onNavigate }: PagesProps) {
474
474
  className="rounded border-gray-300"
475
475
  />
476
476
  </td>
477
- <td className="px-1 py-2 cursor-grab">
478
- <GripVertical className="w-4 h-4 text-gray-300" />
477
+ <td className="cursor-grab px-1 py-2">
478
+ <GripVertical className="h-4 w-4 text-gray-300" />
479
479
  </td>
480
480
  <td className="px-3 py-2">
481
481
  <button
482
482
  type="button"
483
483
  onClick={() => onNavigate?.(`/pages/${page.id}`)}
484
- className="font-medium text-gray-900 hover:text-blue-600 text-sm text-left"
484
+ className="text-left text-sm font-medium text-gray-900 hover:text-blue-600"
485
485
  >
486
486
  {page.title}
487
487
  </button>
@@ -499,7 +499,7 @@ export function Pages({ onNavigate }: PagesProps) {
499
499
  </td>
500
500
  <td className="px-3 py-2">
501
501
  <span
502
- className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
502
+ className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
503
503
  >
504
504
  {page.status}
505
505
  </span>
@@ -510,18 +510,18 @@ export function Pages({ onNavigate }: PagesProps) {
510
510
  <button
511
511
  type="button"
512
512
  onClick={() => onNavigate?.(`/pages/${page.id}`)}
513
- className="p-1.5 hover:bg-gray-100 rounded transition-colors"
513
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
514
514
  title="Edit"
515
515
  >
516
- <Pencil className="w-4 h-4 text-gray-600" />
516
+ <Pencil className="h-4 w-4 text-gray-600" />
517
517
  </button>
518
518
  <button
519
519
  type="button"
520
520
  onClick={() => handleDelete(page.id)}
521
- className="p-1.5 hover:bg-gray-100 rounded transition-colors"
521
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
522
522
  title="Delete"
523
523
  >
524
- <Trash2 className="w-4 h-4 text-red-600" />
524
+ <Trash2 className="h-4 w-4 text-red-600" />
525
525
  </button>
526
526
  </div>
527
527
  </td>
@@ -533,7 +533,7 @@ export function Pages({ onNavigate }: PagesProps) {
533
533
  </div>
534
534
  </div>
535
535
 
536
- <div className="md:hidden bg-white rounded-lg border border-gray-200 flex-1 overflow-auto">
536
+ <div className="flex-1 overflow-auto rounded-lg border border-gray-200 bg-white md:hidden">
537
537
  <div className="divide-y divide-gray-200">
538
538
  {filteredAndSorted.map((page: any) => {
539
539
  const seoScore = computeSeoScore(page.data)
@@ -550,24 +550,24 @@ export function Pages({ onNavigate }: PagesProps) {
550
550
  type="checkbox"
551
551
  checked={selectedPages.includes(page.id)}
552
552
  onChange={() => handleSelectPage(page.id)}
553
- className="rounded border-gray-300 mt-1"
553
+ className="mt-1 rounded border-gray-300"
554
554
  />
555
- <div className="flex-1 min-w-0">
555
+ <div className="min-w-0 flex-1">
556
556
  <button
557
557
  type="button"
558
558
  onClick={() => onNavigate?.(`/pages/${page.id}`)}
559
- className="font-medium text-sm text-gray-900 hover:text-blue-600 block mb-1 text-left"
559
+ className="mb-1 block text-left text-sm font-medium text-gray-900 hover:text-blue-600"
560
560
  >
561
561
  {page.title}
562
562
  </button>
563
- <div className="flex flex-wrap items-center gap-2 text-xs text-gray-600 mb-2">
563
+ <div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-gray-600">
564
564
  {folderName && <FolderBadge name={folderName} />}
565
565
  <span>{page.author}</span>
566
566
  <span>&middot;</span>
567
567
  <span>{page.date}</span>
568
568
  <SeoScoreBadge score={seoScore} />
569
569
  <span
570
- className={`px-2 py-0.5 rounded-full text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
570
+ className={`rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
571
571
  >
572
572
  {page.status}
573
573
  </span>
@@ -576,9 +576,9 @@ export function Pages({ onNavigate }: PagesProps) {
576
576
  <button
577
577
  type="button"
578
578
  onClick={() => handleDelete(page.id)}
579
- className="p-1.5 hover:bg-gray-100 rounded transition-colors"
579
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
580
580
  >
581
- <Trash2 className="w-4 h-4 text-red-600" />
581
+ <Trash2 className="h-4 w-4 text-red-600" />
582
582
  </button>
583
583
  </div>
584
584
  </div>