@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
@@ -298,8 +298,8 @@ export function DocumentEdit({
298
298
 
299
299
  if (loading) {
300
300
  return (
301
- <div className="flex items-center justify-center min-h-[300px]">
302
- <Loader2 className="w-8 h-8 animate-spin text-gray-400" />
301
+ <div className="flex min-h-[300px] items-center justify-center">
302
+ <Loader2 className="h-8 w-8 animate-spin text-gray-400" />
303
303
  </div>
304
304
  )
305
305
  }
@@ -310,12 +310,12 @@ export function DocumentEdit({
310
310
  <div className="flex items-center gap-3">
311
311
  <h1 className="text-2xl font-bold">{displayTitle}</h1>
312
312
  <span
313
- className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${statusColor}`}
313
+ className={`inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${statusColor}`}
314
314
  >
315
315
  {docStatus}
316
316
  </span>
317
317
  {documentId && <PresenceIndicator documentId={documentId} />}
318
- {isDirty && <span className="text-xs text-amber-600 font-medium">Unsaved changes</span>}
318
+ {isDirty && <span className="text-xs font-medium text-amber-600">Unsaved changes</span>}
319
319
  </div>
320
320
  <div className="flex items-center gap-2">
321
321
  <button
@@ -360,11 +360,11 @@ export function DocumentEdit({
360
360
  <div className={showPreview ? 'grid grid-cols-2 gap-6' : ''}>
361
361
  <div className="space-y-6">
362
362
  {fields.length === 0 ? (
363
- <div className="flex flex-col items-center justify-center py-16 text-center rounded-lg border border-[var(--border)]">
364
- <div className="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-4">
365
- <AlertTriangle className="w-6 h-6 text-gray-400" />
363
+ <div className="flex flex-col items-center justify-center rounded-lg border border-[var(--border)] py-16 text-center">
364
+ <div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-gray-100">
365
+ <AlertTriangle className="h-6 w-6 text-gray-400" />
366
366
  </div>
367
- <h3 className="text-sm font-medium text-gray-900 mb-1">
367
+ <h3 className="mb-1 text-sm font-medium text-gray-900">
368
368
  Collection schema not found
369
369
  </h3>
370
370
  <p className="text-sm text-gray-500">No fields are defined for this collection.</p>
@@ -517,7 +517,7 @@ export function DocumentEdit({
517
517
  Cancel
518
518
  </Button>
519
519
  <Button variant="primary" loading={saving} onClick={handleSave} data-shortcut="save">
520
- <Save className="h-4 w-4 mr-1.5" />
520
+ <Save className="mr-1.5 h-4 w-4" />
521
521
  {isNew ? 'Create' : 'Save Changes'}
522
522
  </Button>
523
523
  </div>
@@ -42,25 +42,25 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
42
42
  }
43
43
 
44
44
  return (
45
- <div className="min-h-screen flex items-center justify-center bg-gray-50 px-4">
45
+ <div className="flex min-h-screen items-center justify-center bg-gray-50 px-4">
46
46
  <div className="w-full max-w-md">
47
- <div className="text-center mb-8">
48
- <div className="mx-auto mb-4 w-14 h-14 bg-blue-600 rounded-xl flex items-center justify-center">
49
- <Shield className="w-7 h-7 text-white" />
47
+ <div className="mb-8 text-center">
48
+ <div className="mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-blue-600">
49
+ <Shield className="h-7 w-7 text-white" />
50
50
  </div>
51
51
  <h1 className="text-2xl font-bold text-gray-900">Reset Password</h1>
52
- <p className="text-gray-600 mt-2">
52
+ <p className="mt-2 text-gray-600">
53
53
  {sent
54
54
  ? 'Check your inbox for a reset link'
55
55
  : "Enter your email and we'll send you a reset link"}
56
56
  </p>
57
57
  </div>
58
58
 
59
- <div className="bg-white rounded-xl border border-gray-200 p-6 shadow-sm space-y-5">
59
+ <div className="space-y-5 rounded-xl border border-gray-200 bg-white p-6 shadow-sm">
60
60
  {sent ? (
61
- <div className="text-center space-y-4">
62
- <div className="mx-auto w-12 h-12 bg-green-100 rounded-full flex items-center justify-center">
63
- <CheckCircle2 className="w-6 h-6 text-green-600" />
61
+ <div className="space-y-4 text-center">
62
+ <div className="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
63
+ <CheckCircle2 className="h-6 w-6 text-green-600" />
64
64
  </div>
65
65
  <p className="text-sm text-gray-600">
66
66
  If an account exists for <strong>{email}</strong>, you will receive a password reset
@@ -72,7 +72,7 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
72
72
  <button
73
73
  type="button"
74
74
  onClick={() => onNavigate('/login')}
75
- className="w-full py-2.5 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors"
75
+ className="w-full rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700"
76
76
  >
77
77
  Back to Sign In
78
78
  </button>
@@ -80,8 +80,8 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
80
80
  ) : (
81
81
  <form onSubmit={handleSubmit} className="space-y-5">
82
82
  {error && (
83
- <div className="flex items-start gap-3 p-3 bg-red-50 border border-red-200 rounded-lg">
84
- <AlertTriangle className="w-5 h-5 text-red-600 mt-0.5 shrink-0" />
83
+ <div className="flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
84
+ <AlertTriangle className="mt-0.5 h-5 w-5 shrink-0 text-red-600" />
85
85
  <p className="text-sm text-red-800">{error}</p>
86
86
  </div>
87
87
  )}
@@ -89,7 +89,7 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
89
89
  <div>
90
90
  <label
91
91
  htmlFor="forgot-email"
92
- className="block text-sm font-medium text-gray-700 mb-1.5"
92
+ className="mb-1.5 block text-sm font-medium text-gray-700"
93
93
  >
94
94
  Email Address
95
95
  </label>
@@ -99,7 +99,7 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
99
99
  value={email}
100
100
  onChange={(e) => setEmail(e.target.value)}
101
101
  placeholder="admin@example.com"
102
- className="w-full px-3 py-2.5 border border-gray-300 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
102
+ className="w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none"
103
103
  required
104
104
  autoFocus
105
105
  autoComplete="email"
@@ -109,11 +109,11 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
109
109
  <button
110
110
  type="submit"
111
111
  disabled={!canSubmit}
112
- className="w-full py-2.5 bg-blue-600 text-white rounded-lg font-medium hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
112
+ className="flex w-full items-center justify-center gap-2 rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50"
113
113
  >
114
114
  {submitting ? (
115
115
  <>
116
- <Loader2 className="w-4 h-4 animate-spin" />
116
+ <Loader2 className="h-4 w-4 animate-spin" />
117
117
  Sending...
118
118
  </>
119
119
  ) : (
@@ -127,9 +127,9 @@ export function ForgotPassword({ onNavigate }: ForgotPasswordProps) {
127
127
  <button
128
128
  type="button"
129
129
  onClick={() => onNavigate('/login')}
130
- className="w-full flex items-center justify-center gap-2 text-sm text-gray-600 hover:text-gray-800 transition-colors"
130
+ className="flex w-full items-center justify-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-800"
131
131
  >
132
- <ArrowLeft className="w-4 h-4" />
132
+ <ArrowLeft className="h-4 w-4" />
133
133
  Back to Sign In
134
134
  </button>
135
135
  )}
@@ -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>