@actuate-media/cms-admin 0.9.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 (294) 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.d.ts +18 -0
  34. package/dist/components/SchedulePublishDialog.d.ts.map +1 -0
  35. package/dist/components/SchedulePublishDialog.js +106 -0
  36. package/dist/components/SchedulePublishDialog.js.map +1 -0
  37. package/dist/components/SharePreviewLinkDialog.d.ts +17 -0
  38. package/dist/components/SharePreviewLinkDialog.d.ts.map +1 -0
  39. package/dist/components/SharePreviewLinkDialog.js +83 -0
  40. package/dist/components/SharePreviewLinkDialog.js.map +1 -0
  41. package/dist/components/TipTapEditor.js +5 -5
  42. package/dist/components/VersionHistory.js +2 -2
  43. package/dist/components/ui/Badge.d.ts +33 -3
  44. package/dist/components/ui/Badge.d.ts.map +1 -1
  45. package/dist/components/ui/Badge.js +42 -8
  46. package/dist/components/ui/Badge.js.map +1 -1
  47. package/dist/components/ui/Button.d.ts +19 -8
  48. package/dist/components/ui/Button.d.ts.map +1 -1
  49. package/dist/components/ui/Button.js +35 -14
  50. package/dist/components/ui/Button.js.map +1 -1
  51. package/dist/components/ui/Card.d.ts +26 -0
  52. package/dist/components/ui/Card.d.ts.map +1 -0
  53. package/dist/components/ui/Card.js +45 -0
  54. package/dist/components/ui/Card.js.map +1 -0
  55. package/dist/components/ui/DataTable.js +1 -1
  56. package/dist/components/ui/Input.d.ts +15 -0
  57. package/dist/components/ui/Input.d.ts.map +1 -0
  58. package/dist/components/ui/Input.js +23 -0
  59. package/dist/components/ui/Input.js.map +1 -0
  60. package/dist/components/ui/SearchInput.js +1 -1
  61. package/dist/components/ui/Select.d.ts +16 -0
  62. package/dist/components/ui/Select.d.ts.map +1 -0
  63. package/dist/components/ui/Select.js +25 -0
  64. package/dist/components/ui/Select.js.map +1 -0
  65. package/dist/components/ui/Toast.js +1 -1
  66. package/dist/components/ui/index.d.ts +10 -4
  67. package/dist/components/ui/index.d.ts.map +1 -1
  68. package/dist/components/ui/index.js +5 -2
  69. package/dist/components/ui/index.js.map +1 -1
  70. package/dist/fields/BlockBuilderField.js +3 -3
  71. package/dist/fields/DateField.js +1 -1
  72. package/dist/fields/RelationshipField.js +3 -3
  73. package/dist/fields/TextField.js +1 -1
  74. package/dist/index.d.ts +6 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +5 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/layout/Header.js +1 -1
  79. package/dist/layout/Layout.d.ts +14 -0
  80. package/dist/layout/Layout.d.ts.map +1 -1
  81. package/dist/layout/Layout.js +17 -11
  82. package/dist/layout/Layout.js.map +1 -1
  83. package/dist/layout/Sidebar.d.ts.map +1 -1
  84. package/dist/layout/Sidebar.js +21 -11
  85. package/dist/layout/Sidebar.js.map +1 -1
  86. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  87. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  88. package/dist/layout/primitives/AdminShell.js +51 -0
  89. package/dist/layout/primitives/AdminShell.js.map +1 -0
  90. package/dist/layout/primitives/Box.d.ts +19 -0
  91. package/dist/layout/primitives/Box.d.ts.map +1 -0
  92. package/dist/layout/primitives/Box.js +12 -0
  93. package/dist/layout/primitives/Box.js.map +1 -0
  94. package/dist/layout/primitives/Cluster.d.ts +27 -0
  95. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  96. package/dist/layout/primitives/Cluster.js +37 -0
  97. package/dist/layout/primitives/Cluster.js.map +1 -0
  98. package/dist/layout/primitives/Grid.d.ts +45 -0
  99. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  100. package/dist/layout/primitives/Grid.js +59 -0
  101. package/dist/layout/primitives/Grid.js.map +1 -0
  102. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  103. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  104. package/dist/layout/primitives/PageContainer.js +41 -0
  105. package/dist/layout/primitives/PageContainer.js.map +1 -0
  106. package/dist/layout/primitives/Split.d.ts +34 -0
  107. package/dist/layout/primitives/Split.d.ts.map +1 -0
  108. package/dist/layout/primitives/Split.js +27 -0
  109. package/dist/layout/primitives/Split.js.map +1 -0
  110. package/dist/layout/primitives/Stack.d.ts +23 -0
  111. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  112. package/dist/layout/primitives/Stack.js +34 -0
  113. package/dist/layout/primitives/Stack.js.map +1 -0
  114. package/dist/layout/primitives/index.d.ts +30 -0
  115. package/dist/layout/primitives/index.d.ts.map +1 -0
  116. package/dist/layout/primitives/index.js +22 -0
  117. package/dist/layout/primitives/index.js.map +1 -0
  118. package/dist/layout/primitives/tokens.d.ts +48 -0
  119. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  120. package/dist/layout/primitives/tokens.js +54 -0
  121. package/dist/layout/primitives/tokens.js.map +1 -0
  122. package/dist/lib/cv.d.ts +53 -0
  123. package/dist/lib/cv.d.ts.map +1 -0
  124. package/dist/lib/cv.js +39 -0
  125. package/dist/lib/cv.js.map +1 -0
  126. package/dist/views/ApiKeys.d.ts.map +1 -1
  127. package/dist/views/ApiKeys.js +13 -11
  128. package/dist/views/ApiKeys.js.map +1 -1
  129. package/dist/views/CollectionList.js +8 -8
  130. package/dist/views/Dashboard.d.ts.map +1 -1
  131. package/dist/views/Dashboard.js +333 -78
  132. package/dist/views/Dashboard.js.map +1 -1
  133. package/dist/views/DocumentEdit.d.ts.map +1 -1
  134. package/dist/views/DocumentEdit.js +17 -5
  135. package/dist/views/DocumentEdit.js.map +1 -1
  136. package/dist/views/ForgotPassword.js +2 -2
  137. package/dist/views/FormEditor.js +5 -5
  138. package/dist/views/FormSubmissions.js +6 -6
  139. package/dist/views/Forms.js +2 -2
  140. package/dist/views/Login.d.ts +16 -1
  141. package/dist/views/Login.d.ts.map +1 -1
  142. package/dist/views/Login.js +17 -7
  143. package/dist/views/Login.js.map +1 -1
  144. package/dist/views/MediaBrowser.js +16 -16
  145. package/dist/views/PageEditor.js +2 -2
  146. package/dist/views/Pages.js +10 -10
  147. package/dist/views/PostEditor.js +2 -2
  148. package/dist/views/Posts.js +4 -4
  149. package/dist/views/Redirects.js +4 -4
  150. package/dist/views/ResetPassword.js +2 -2
  151. package/dist/views/SEO.js +6 -6
  152. package/dist/views/ScriptTagEditor.js +4 -4
  153. package/dist/views/ScriptTags.js +2 -2
  154. package/dist/views/Settings.d.ts.map +1 -1
  155. package/dist/views/Settings.js +9 -8
  156. package/dist/views/Settings.js.map +1 -1
  157. package/dist/views/SetupWizard.js +2 -2
  158. package/dist/views/Users.js +4 -4
  159. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  160. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  161. package/dist/views/page-builder/BlockEditor.js +10 -10
  162. package/dist/views/page-builder/BlockPicker.js +4 -4
  163. package/dist/views/page-builder/BottomBar.js +1 -1
  164. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  165. package/dist/views/page-builder/ContextPanel.js +2 -2
  166. package/dist/views/page-builder/DesignScore.js +9 -9
  167. package/dist/views/page-builder/NodeSettings.js +8 -8
  168. package/dist/views/page-builder/PageBuilder.js +3 -3
  169. package/dist/views/page-builder/PageSettings.js +1 -1
  170. package/dist/views/page-builder/PageTemplates.js +2 -2
  171. package/dist/views/page-builder/SEOPanel.js +13 -13
  172. package/dist/views/page-builder/SavedSections.js +5 -5
  173. package/dist/views/page-builder/TemplatePicker.js +2 -2
  174. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  175. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  176. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  177. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  178. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  179. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  180. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  181. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  182. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  183. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  184. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  185. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  186. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  187. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  188. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  189. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  190. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  191. package/package.json +6 -2
  192. package/src/AdminRoot.tsx +21 -11
  193. package/src/__tests__/layout/primitives.test.ts +37 -0
  194. package/src/__tests__/lib/cv.test.ts +74 -0
  195. package/src/assets/actuate-logo.tsx +72 -0
  196. package/src/components/Breadcrumbs.tsx +6 -6
  197. package/src/components/CommandPalette.tsx +34 -34
  198. package/src/components/ContentOverviewChart.tsx +3 -3
  199. package/src/components/ErrorBoundary.tsx +3 -3
  200. package/src/components/FocalPointPicker.tsx +4 -4
  201. package/src/components/FolderTree.tsx +38 -38
  202. package/src/components/LivePreview.tsx +16 -16
  203. package/src/components/LocaleSwitcher.tsx +7 -7
  204. package/src/components/MediaPickerModal.tsx +21 -21
  205. package/src/components/PresenceIndicator.tsx +2 -2
  206. package/src/components/SEOConfigPanel.tsx +582 -0
  207. package/src/components/SEOPanel.tsx +46 -46
  208. package/src/components/SEOPerformance.tsx +21 -21
  209. package/src/components/SchedulePublishDialog.tsx +241 -0
  210. package/src/components/SharePreviewLinkDialog.tsx +227 -0
  211. package/src/components/TipTapEditor.tsx +33 -33
  212. package/src/components/VersionHistory.tsx +16 -16
  213. package/src/components/ui/Badge.tsx +66 -14
  214. package/src/components/ui/Button.tsx +70 -33
  215. package/src/components/ui/Card.tsx +101 -0
  216. package/src/components/ui/DataTable.tsx +1 -1
  217. package/src/components/ui/Input.tsx +35 -0
  218. package/src/components/ui/SearchInput.tsx +4 -4
  219. package/src/components/ui/Select.tsx +56 -0
  220. package/src/components/ui/Toast.tsx +1 -1
  221. package/src/components/ui/index.ts +18 -4
  222. package/src/fields/BlockBuilderField.tsx +3 -3
  223. package/src/fields/DateField.tsx +1 -1
  224. package/src/fields/RelationshipField.tsx +10 -10
  225. package/src/fields/TextField.tsx +1 -1
  226. package/src/index.ts +32 -0
  227. package/src/layout/Header.tsx +28 -28
  228. package/src/layout/Layout.tsx +39 -46
  229. package/src/layout/Sidebar.tsx +37 -64
  230. package/src/layout/primitives/AdminShell.tsx +118 -0
  231. package/src/layout/primitives/Box.tsx +30 -0
  232. package/src/layout/primitives/Cluster.tsx +74 -0
  233. package/src/layout/primitives/Grid.tsx +120 -0
  234. package/src/layout/primitives/PageContainer.tsx +96 -0
  235. package/src/layout/primitives/Split.tsx +73 -0
  236. package/src/layout/primitives/Stack.tsx +67 -0
  237. package/src/layout/primitives/index.ts +36 -0
  238. package/src/layout/primitives/tokens.ts +76 -0
  239. package/src/lib/cv.ts +96 -0
  240. package/src/styles/build-input.css +1 -1
  241. package/src/views/ApiKeys.tsx +57 -57
  242. package/src/views/CollectionList.tsx +30 -30
  243. package/src/views/Dashboard.tsx +737 -186
  244. package/src/views/DocumentEdit.tsx +90 -10
  245. package/src/views/ForgotPassword.tsx +18 -18
  246. package/src/views/FormEditor.tsx +75 -75
  247. package/src/views/FormSubmissions.tsx +76 -76
  248. package/src/views/Forms.tsx +27 -27
  249. package/src/views/Login.tsx +65 -25
  250. package/src/views/MediaBrowser.tsx +127 -127
  251. package/src/views/PageEditor.tsx +25 -25
  252. package/src/views/Pages.tsx +59 -59
  253. package/src/views/PostEditor.tsx +37 -37
  254. package/src/views/Posts.tsx +48 -48
  255. package/src/views/Redirects.tsx +21 -21
  256. package/src/views/ResetPassword.tsx +28 -28
  257. package/src/views/SEO.tsx +144 -144
  258. package/src/views/ScriptTagEditor.tsx +24 -24
  259. package/src/views/ScriptTags.tsx +10 -10
  260. package/src/views/Settings.tsx +88 -80
  261. package/src/views/SetupWizard.tsx +28 -28
  262. package/src/views/Users.tsx +20 -20
  263. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  264. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  265. package/src/views/page-builder/BlockEditor.tsx +26 -26
  266. package/src/views/page-builder/BlockPicker.tsx +22 -22
  267. package/src/views/page-builder/BottomBar.tsx +8 -8
  268. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  269. package/src/views/page-builder/ContextPanel.tsx +3 -3
  270. package/src/views/page-builder/DesignScore.tsx +21 -21
  271. package/src/views/page-builder/NodeSettings.tsx +27 -27
  272. package/src/views/page-builder/PageBuilder.tsx +11 -11
  273. package/src/views/page-builder/PageSettings.tsx +4 -4
  274. package/src/views/page-builder/PageTemplates.tsx +18 -18
  275. package/src/views/page-builder/SEOPanel.tsx +53 -53
  276. package/src/views/page-builder/SavedSections.tsx +37 -37
  277. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  278. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  279. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  280. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  281. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  282. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  283. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  284. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  285. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  286. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  287. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  288. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  289. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  290. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  291. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  292. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  293. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  294. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -174,21 +174,21 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
174
174
 
175
175
  if (loading) {
176
176
  return (
177
- <div className="p-4 flex items-center justify-center h-64">
178
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
177
+ <div className="flex h-64 items-center justify-center p-4">
178
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
179
179
  </div>
180
180
  )
181
181
  }
182
182
 
183
183
  return (
184
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 max-w-4xl">
184
+ <div className="max-w-4xl p-3 pr-6 sm:p-4 sm:pr-8">
185
185
  {/* Header */}
186
- <div className="flex items-center gap-3 mb-6">
186
+ <div className="mb-6 flex items-center gap-3">
187
187
  <button
188
188
  onClick={() => onNavigate?.('/forms')}
189
- className="p-2 hover:bg-gray-100 rounded-lg transition-colors"
189
+ className="rounded-lg p-2 transition-colors hover:bg-gray-100"
190
190
  >
191
- <ArrowLeft className="w-5 h-5 text-gray-600" />
191
+ <ArrowLeft className="h-5 w-5 text-gray-600" />
192
192
  </button>
193
193
  <div className="flex-1">
194
194
  <h1 className="text-xl font-semibold text-gray-900">
@@ -198,42 +198,42 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
198
198
  <button
199
199
  onClick={handleSave}
200
200
  disabled={saving || !name.trim()}
201
- className="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm disabled:opacity-50"
201
+ className="flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700 disabled:opacity-50"
202
202
  >
203
- {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
203
+ {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Save className="h-4 w-4" />}
204
204
  {saving ? 'Saving...' : 'Save'}
205
205
  </button>
206
206
  </div>
207
207
 
208
208
  {/* Basic info */}
209
- <div className="bg-white rounded-lg border border-gray-200 p-4 mb-4">
209
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white p-4">
210
210
  <div className="grid gap-4">
211
211
  <div>
212
- <label className="block text-sm font-medium text-gray-700 mb-1">Form Name</label>
212
+ <label className="mb-1 block text-sm font-medium text-gray-700">Form Name</label>
213
213
  <input
214
214
  type="text"
215
215
  value={name}
216
216
  onChange={(e) => setName(e.target.value)}
217
217
  placeholder="e.g. Contact Form"
218
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
218
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
219
219
  />
220
220
  </div>
221
221
  <div>
222
- <label className="block text-sm font-medium text-gray-700 mb-1">Description</label>
222
+ <label className="mb-1 block text-sm font-medium text-gray-700">Description</label>
223
223
  <input
224
224
  type="text"
225
225
  value={description}
226
226
  onChange={(e) => setDescription(e.target.value)}
227
227
  placeholder="Brief description of this form"
228
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
228
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
229
229
  />
230
230
  </div>
231
231
  <div>
232
- <label className="block text-sm font-medium text-gray-700 mb-1">Status</label>
232
+ <label className="mb-1 block text-sm font-medium text-gray-700">Status</label>
233
233
  <select
234
234
  value={status}
235
235
  onChange={(e) => setStatus(e.target.value)}
236
- className="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
236
+ className="rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
237
237
  >
238
238
  <option value="active">Active</option>
239
239
  <option value="inactive">Inactive</option>
@@ -243,16 +243,16 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
243
243
  </div>
244
244
 
245
245
  {/* Fields section */}
246
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
246
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
247
247
  <button
248
248
  onClick={() => toggleSection('fields')}
249
- className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
249
+ className="flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50"
250
250
  >
251
251
  <div className="flex items-center gap-2">
252
252
  {expandedSection === 'fields' ? (
253
- <ChevronDown className="w-4 h-4" />
253
+ <ChevronDown className="h-4 w-4" />
254
254
  ) : (
255
- <ChevronRight className="w-4 h-4" />
255
+ <ChevronRight className="h-4 w-4" />
256
256
  )}
257
257
  <span className="font-medium text-gray-900">Form Fields</span>
258
258
  <span className="text-sm text-gray-500">({fields.length})</span>
@@ -260,20 +260,20 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
260
260
  </button>
261
261
  {expandedSection === 'fields' && (
262
262
  <div className="border-t border-gray-200 p-4">
263
- <div className="flex flex-wrap gap-2 mb-4">
263
+ <div className="mb-4 flex flex-wrap gap-2">
264
264
  {FIELD_TYPES.map((ft) => (
265
265
  <button
266
266
  key={ft.value}
267
267
  onClick={() => addField(ft.value)}
268
- className="flex items-center gap-1 px-3 py-1.5 text-xs border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
268
+ className="flex items-center gap-1 rounded-lg border border-gray-300 px-3 py-1.5 text-xs transition-colors hover:bg-gray-50"
269
269
  >
270
- <Plus className="w-3 h-3" /> {ft.label}
270
+ <Plus className="h-3 w-3" /> {ft.label}
271
271
  </button>
272
272
  ))}
273
273
  </div>
274
274
 
275
275
  {fields.length === 0 ? (
276
- <p className="text-sm text-gray-500 text-center py-6">
276
+ <p className="py-6 text-center text-sm text-gray-500">
277
277
  Click a field type above to add it to your form.
278
278
  </p>
279
279
  ) : (
@@ -288,19 +288,19 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
288
288
  const from = Number(e.dataTransfer.getData('text/plain'))
289
289
  moveField(from, index)
290
290
  }}
291
- className="flex items-center gap-3 p-3 border border-gray-200 rounded-lg bg-gray-50 hover:bg-white transition-colors"
291
+ className="flex items-center gap-3 rounded-lg border border-gray-200 bg-gray-50 p-3 transition-colors hover:bg-white"
292
292
  >
293
- <GripVertical className="w-4 h-4 text-gray-400 cursor-grab shrink-0" />
293
+ <GripVertical className="h-4 w-4 shrink-0 cursor-grab text-gray-400" />
294
294
  <input
295
295
  type="text"
296
296
  value={field.label}
297
297
  onChange={(e) => updateField(field.id, { label: e.target.value })}
298
- className="flex-1 px-2 py-1 text-sm border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
298
+ className="flex-1 rounded border border-gray-300 px-2 py-1 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none"
299
299
  />
300
- <span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded shrink-0">
300
+ <span className="shrink-0 rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-500">
301
301
  {field.type}
302
302
  </span>
303
- <label className="flex items-center gap-1 text-xs text-gray-600 shrink-0">
303
+ <label className="flex shrink-0 items-center gap-1 text-xs text-gray-600">
304
304
  <input
305
305
  type="checkbox"
306
306
  checked={field.required}
@@ -311,9 +311,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
311
311
  </label>
312
312
  <button
313
313
  onClick={() => removeField(field.id)}
314
- className="p-1 text-red-500 hover:bg-red-50 rounded transition-colors shrink-0"
314
+ className="shrink-0 rounded p-1 text-red-500 transition-colors hover:bg-red-50"
315
315
  >
316
- <Trash2 className="w-4 h-4" />
316
+ <Trash2 className="h-4 w-4" />
317
317
  </button>
318
318
  </div>
319
319
  ))}
@@ -324,20 +324,20 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
324
324
  </div>
325
325
 
326
326
  {/* Confirmation section */}
327
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
327
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
328
328
  <button
329
329
  onClick={() => toggleSection('confirmation')}
330
- className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
330
+ className="flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50"
331
331
  >
332
332
  <div className="flex items-center gap-2">
333
333
  {expandedSection === 'confirmation' ? (
334
- <ChevronDown className="w-4 h-4" />
334
+ <ChevronDown className="h-4 w-4" />
335
335
  ) : (
336
- <ChevronRight className="w-4 h-4" />
336
+ <ChevronRight className="h-4 w-4" />
337
337
  )}
338
- <MessageSquare className="w-4 h-4 text-green-600" />
338
+ <MessageSquare className="h-4 w-4 text-green-600" />
339
339
  <span className="font-medium text-gray-900">Confirmation</span>
340
- <span className="text-xs text-gray-500 bg-gray-100 px-2 py-0.5 rounded">
340
+ <span className="rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-500">
341
341
  {confirmation.type === 'message' ? 'Show Message' : 'Redirect'}
342
342
  </span>
343
343
  </div>
@@ -345,12 +345,12 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
345
345
  {expandedSection === 'confirmation' && (
346
346
  <div className="border-t border-gray-200 p-4">
347
347
  <div className="mb-4">
348
- <label className="block text-sm font-medium text-gray-700 mb-2">
348
+ <label className="mb-2 block text-sm font-medium text-gray-700">
349
349
  After submission
350
350
  </label>
351
351
  <div className="flex gap-3">
352
352
  <label
353
- className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
353
+ className="flex cursor-pointer items-center gap-2 rounded-lg border px-4 py-2 transition-colors hover:bg-gray-50"
354
354
  style={{
355
355
  borderColor: confirmation.type === 'message' ? '#2563eb' : '#d1d5db',
356
356
  backgroundColor: confirmation.type === 'message' ? '#eff6ff' : 'transparent',
@@ -364,11 +364,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
364
364
  onChange={() => setConfirmation((c) => ({ ...c, type: 'message' }))}
365
365
  className="text-blue-600"
366
366
  />
367
- <MessageSquare className="w-4 h-4" />
367
+ <MessageSquare className="h-4 w-4" />
368
368
  <span className="text-sm">Show Message</span>
369
369
  </label>
370
370
  <label
371
- className="flex items-center gap-2 px-4 py-2 border rounded-lg cursor-pointer transition-colors hover:bg-gray-50"
371
+ className="flex cursor-pointer items-center gap-2 rounded-lg border px-4 py-2 transition-colors hover:bg-gray-50"
372
372
  style={{
373
373
  borderColor: confirmation.type === 'redirect' ? '#2563eb' : '#d1d5db',
374
374
  backgroundColor: confirmation.type === 'redirect' ? '#eff6ff' : 'transparent',
@@ -382,7 +382,7 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
382
382
  onChange={() => setConfirmation((c) => ({ ...c, type: 'redirect' }))}
383
383
  className="text-blue-600"
384
384
  />
385
- <ExternalLink className="w-4 h-4" />
385
+ <ExternalLink className="h-4 w-4" />
386
386
  <span className="text-sm">Redirect to Page</span>
387
387
  </label>
388
388
  </div>
@@ -390,21 +390,21 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
390
390
 
391
391
  {confirmation.type === 'message' ? (
392
392
  <div>
393
- <label className="block text-sm font-medium text-gray-700 mb-1">
393
+ <label className="mb-1 block text-sm font-medium text-gray-700">
394
394
  Success Message
395
395
  </label>
396
396
  <textarea
397
397
  value={confirmation.message}
398
398
  onChange={(e) => setConfirmation((c) => ({ ...c, message: e.target.value }))}
399
399
  rows={3}
400
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
400
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
401
401
  placeholder="Thank you! Your submission has been received."
402
402
  />
403
403
  </div>
404
404
  ) : (
405
405
  <div className="grid gap-3">
406
406
  <div>
407
- <label className="block text-sm font-medium text-gray-700 mb-1">
407
+ <label className="mb-1 block text-sm font-medium text-gray-700">
408
408
  Redirect URL
409
409
  </label>
410
410
  <input
@@ -414,11 +414,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
414
414
  setConfirmation((c) => ({ ...c, redirectUrl: e.target.value }))
415
415
  }
416
416
  placeholder="https://example.com/thank-you"
417
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
417
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
418
418
  />
419
419
  </div>
420
420
  <div>
421
- <label className="block text-sm font-medium text-gray-700 mb-1">
421
+ <label className="mb-1 block text-sm font-medium text-gray-700">
422
422
  Redirect Delay (ms)
423
423
  </label>
424
424
  <input
@@ -429,9 +429,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
429
429
  }
430
430
  min={0}
431
431
  step={500}
432
- className="w-32 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
432
+ className="w-32 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
433
433
  />
434
- <p className="text-xs text-gray-500 mt-1">0 = instant redirect</p>
434
+ <p className="mt-1 text-xs text-gray-500">0 = instant redirect</p>
435
435
  </div>
436
436
  </div>
437
437
  )}
@@ -440,21 +440,21 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
440
440
  </div>
441
441
 
442
442
  {/* Analytics section */}
443
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
443
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
444
444
  <button
445
445
  onClick={() => toggleSection('analytics')}
446
- className="w-full flex items-center justify-between p-4 hover:bg-gray-50 transition-colors"
446
+ className="flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50"
447
447
  >
448
448
  <div className="flex items-center gap-2">
449
449
  {expandedSection === 'analytics' ? (
450
- <ChevronDown className="w-4 h-4" />
450
+ <ChevronDown className="h-4 w-4" />
451
451
  ) : (
452
- <ChevronRight className="w-4 h-4" />
452
+ <ChevronRight className="h-4 w-4" />
453
453
  )}
454
- <BarChart3 className="w-4 h-4 text-purple-600" />
454
+ <BarChart3 className="h-4 w-4 text-purple-600" />
455
455
  <span className="font-medium text-gray-900">GA4 Analytics</span>
456
456
  <span
457
- className={`text-xs px-2 py-0.5 rounded ${analytics.enabled ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`}
457
+ className={`rounded px-2 py-0.5 text-xs ${analytics.enabled ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`}
458
458
  >
459
459
  {analytics.enabled ? 'Enabled' : 'Disabled'}
460
460
  </span>
@@ -462,15 +462,15 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
462
462
  </button>
463
463
  {expandedSection === 'analytics' && (
464
464
  <div className="border-t border-gray-200 p-4">
465
- <div className="flex items-center gap-3 mb-4">
466
- <label className="relative inline-flex items-center cursor-pointer">
465
+ <div className="mb-4 flex items-center gap-3">
466
+ <label className="relative inline-flex cursor-pointer items-center">
467
467
  <input
468
468
  type="checkbox"
469
469
  checked={analytics.enabled}
470
470
  onChange={(e) => setAnalytics((a) => ({ ...a, enabled: e.target.checked }))}
471
- className="sr-only peer"
471
+ className="peer sr-only"
472
472
  />
473
- <div className="w-9 h-5 bg-gray-200 peer-focus:outline-none peer-focus:ring-2 peer-focus:ring-blue-300 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-600" />
473
+ <div className="peer h-5 w-9 rounded-full bg-gray-200 peer-checked:bg-blue-600 peer-focus:ring-2 peer-focus:ring-blue-300 peer-focus:outline-none after:absolute after:top-[2px] after:left-[2px] after:h-4 after:w-4 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white" />
474
474
  </label>
475
475
  <span className="text-sm font-medium text-gray-700">
476
476
  Push events to Google Analytics 4
@@ -480,25 +480,25 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
480
480
  {analytics.enabled && (
481
481
  <div className="grid gap-4 pl-12">
482
482
  <div>
483
- <label className="block text-sm font-medium text-gray-700 mb-1">
483
+ <label className="mb-1 block text-sm font-medium text-gray-700">
484
484
  GA4 Measurement ID
485
- <span className="text-gray-400 font-normal"> (optional)</span>
485
+ <span className="font-normal text-gray-400"> (optional)</span>
486
486
  </label>
487
487
  <input
488
488
  type="text"
489
489
  value={analytics.measurementId}
490
490
  onChange={(e) => setAnalytics((a) => ({ ...a, measurementId: e.target.value }))}
491
491
  placeholder="G-XXXXXXXXXX"
492
- className="w-64 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
492
+ className="w-64 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
493
493
  />
494
- <p className="text-xs text-gray-500 mt-1">
494
+ <p className="mt-1 text-xs text-gray-500">
495
495
  Leave blank to use your site's default GA4 tag
496
496
  </p>
497
497
  </div>
498
498
 
499
499
  <div className="grid grid-cols-2 gap-4">
500
500
  <div>
501
- <label className="block text-sm font-medium text-gray-700 mb-1">
501
+ <label className="mb-1 block text-sm font-medium text-gray-700">
502
502
  Submit Event Name
503
503
  </label>
504
504
  <input
@@ -507,11 +507,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
507
507
  onChange={(e) =>
508
508
  setAnalytics((a) => ({ ...a, submitEventName: e.target.value }))
509
509
  }
510
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
510
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
511
511
  />
512
512
  </div>
513
513
  <div>
514
- <label className="block text-sm font-medium text-gray-700 mb-1">
514
+ <label className="mb-1 block text-sm font-medium text-gray-700">
515
515
  Start Event Name
516
516
  </label>
517
517
  <input
@@ -520,13 +520,13 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
520
520
  onChange={(e) =>
521
521
  setAnalytics((a) => ({ ...a, startEventName: e.target.value }))
522
522
  }
523
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
523
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
524
524
  />
525
525
  </div>
526
526
  </div>
527
527
 
528
528
  <div className="border-t border-gray-200 pt-4">
529
- <div className="flex items-center gap-3 mb-3">
529
+ <div className="mb-3 flex items-center gap-3">
530
530
  <input
531
531
  type="checkbox"
532
532
  id="trackConversion"
@@ -542,9 +542,9 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
542
542
  </div>
543
543
 
544
544
  {analytics.trackAsConversion && (
545
- <div className="grid grid-cols-2 gap-4 ml-6">
545
+ <div className="ml-6 grid grid-cols-2 gap-4">
546
546
  <div>
547
- <label className="block text-sm font-medium text-gray-700 mb-1">
547
+ <label className="mb-1 block text-sm font-medium text-gray-700">
548
548
  Conversion Value
549
549
  </label>
550
550
  <input
@@ -555,11 +555,11 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
555
555
  }
556
556
  min={0}
557
557
  step={0.01}
558
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
558
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
559
559
  />
560
560
  </div>
561
561
  <div>
562
- <label className="block text-sm font-medium text-gray-700 mb-1">
562
+ <label className="mb-1 block text-sm font-medium text-gray-700">
563
563
  Currency
564
564
  </label>
565
565
  <select
@@ -567,7 +567,7 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
567
567
  onChange={(e) =>
568
568
  setAnalytics((a) => ({ ...a, conversionCurrency: e.target.value }))
569
569
  }
570
- className="w-full px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
570
+ className="w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
571
571
  >
572
572
  <option value="USD">USD</option>
573
573
  <option value="EUR">EUR</option>
@@ -580,12 +580,12 @@ export function FormEditor({ formId, onNavigate }: FormEditorProps) {
580
580
  )}
581
581
  </div>
582
582
 
583
- <div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
583
+ <div className="rounded-lg border border-blue-200 bg-blue-50 p-3">
584
584
  <p className="text-xs text-blue-800">
585
585
  <strong>Note:</strong> Your site must have the GA4 snippet or GTM container
586
586
  installed. Actuate pushes events via{' '}
587
- <code className="bg-blue-100 px-1 rounded">gtag()</code> /
588
- <code className="bg-blue-100 px-1 rounded">dataLayer</code> — it does not load
587
+ <code className="rounded bg-blue-100 px-1">gtag()</code> /
588
+ <code className="rounded bg-blue-100 px-1">dataLayer</code> — it does not load
589
589
  the GA4 script.
590
590
  </p>
591
591
  </div>