@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
@@ -67,9 +67,9 @@ function mediumColor(medium: string): string {
67
67
  }
68
68
 
69
69
  function DeviceIcon({ type }: { type: string }) {
70
- if (type === 'Mobile') return <Smartphone className="w-3.5 h-3.5" />
71
- if (type === 'Tablet') return <Tablet className="w-3.5 h-3.5" />
72
- return <Monitor className="w-3.5 h-3.5" />
70
+ if (type === 'Mobile') return <Smartphone className="h-3.5 w-3.5" />
71
+ if (type === 'Tablet') return <Tablet className="h-3.5 w-3.5" />
72
+ return <Monitor className="h-3.5 w-3.5" />
73
73
  }
74
74
 
75
75
  export interface FormSubmissionsProps {
@@ -127,8 +127,8 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
127
127
 
128
128
  if (loading) {
129
129
  return (
130
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
131
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
130
+ <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
131
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
132
132
  </div>
133
133
  )
134
134
  }
@@ -137,11 +137,11 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
137
137
  <div className="p-3 pr-6 sm:p-4 sm:pr-8">
138
138
  {error && (
139
139
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
140
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
141
- <span className="text-sm text-red-800 flex-1">{error}</span>
140
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
141
+ <span className="flex-1 text-sm text-red-800">{error}</span>
142
142
  <button
143
143
  onClick={refetch}
144
- className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
144
+ className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
145
145
  >
146
146
  Retry
147
147
  </button>
@@ -151,14 +151,14 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
151
151
  <div className="mb-4">
152
152
  <button
153
153
  onClick={() => onNavigate?.('/forms')}
154
- className="inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 transition-colors mb-3"
154
+ className="mb-3 inline-flex items-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-900"
155
155
  >
156
- <ArrowLeft className="w-4 h-4" />
156
+ <ArrowLeft className="h-4 w-4" />
157
157
  Back to Forms
158
158
  </button>
159
159
  <div className="flex items-center justify-between">
160
160
  <div>
161
- <h1 className="text-2xl font-semibold text-gray-900 mb-1">
161
+ <h1 className="mb-1 text-2xl font-semibold text-gray-900">
162
162
  Contact Form - Submissions
163
163
  </h1>
164
164
  <p className="text-sm text-gray-600">
@@ -167,49 +167,49 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
167
167
  </div>
168
168
  <button
169
169
  onClick={handleExport}
170
- 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"
170
+ 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"
171
171
  >
172
- <Download className="w-4 h-4" />
172
+ <Download className="h-4 w-4" />
173
173
  Export CSV
174
174
  </button>
175
175
  </div>
176
176
  </div>
177
177
 
178
- <div className="grid grid-cols-2 md:grid-cols-5 gap-3 mb-4">
179
- <div className="bg-white rounded-lg border border-gray-200 p-4">
180
- <div className="text-xs text-gray-600 mb-1">Total</div>
178
+ <div className="mb-4 grid grid-cols-2 gap-3 md:grid-cols-5">
179
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
180
+ <div className="mb-1 text-xs text-gray-600">Total</div>
181
181
  <div className="text-2xl font-semibold text-gray-900">{submissions.length}</div>
182
182
  </div>
183
- <div className="bg-white rounded-lg border border-gray-200 p-4">
184
- <div className="text-xs text-gray-600 mb-1">New</div>
183
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
184
+ <div className="mb-1 text-xs text-gray-600">New</div>
185
185
  <div className="text-2xl font-semibold text-blue-600">
186
186
  {submissions.filter((s) => s.status === 'new').length}
187
187
  </div>
188
188
  </div>
189
- <div className="bg-white rounded-lg border border-gray-200 p-4">
190
- <div className="text-xs text-gray-600 mb-1">Paid Traffic</div>
189
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
190
+ <div className="mb-1 text-xs text-gray-600">Paid Traffic</div>
191
191
  <div className="text-2xl font-semibold text-orange-600">{paidCount}</div>
192
192
  </div>
193
- <div className="bg-white rounded-lg border border-gray-200 p-4">
194
- <div className="text-xs text-gray-600 mb-1">Organic</div>
193
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
194
+ <div className="mb-1 text-xs text-gray-600">Organic</div>
195
195
  <div className="text-2xl font-semibold text-green-600">{organicCount}</div>
196
196
  </div>
197
- <div className="bg-white rounded-lg border border-gray-200 p-4">
198
- <div className="text-xs text-gray-600 mb-1">Top Source</div>
197
+ <div className="rounded-lg border border-gray-200 bg-white p-4">
198
+ <div className="mb-1 text-xs text-gray-600">Top Source</div>
199
199
  <div className="text-lg font-semibold text-gray-900">{sourceSummary[0]?.[0] ?? '—'}</div>
200
200
  </div>
201
201
  </div>
202
202
 
203
- <div className="bg-white rounded-lg border border-gray-200 p-4 mb-4">
204
- <h3 className="text-sm font-semibold text-gray-900 mb-3 flex items-center gap-2">
205
- <Globe className="w-4 h-4 text-blue-600" />
203
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white p-4">
204
+ <h3 className="mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900">
205
+ <Globe className="h-4 w-4 text-blue-600" />
206
206
  Lead Source Breakdown
207
207
  </h3>
208
208
  <div className="flex flex-wrap gap-2">
209
209
  {sourceSummary.map(([label, count]) => (
210
- <div key={label} className="flex items-center gap-2 px-3 py-1.5 bg-gray-50 rounded-lg">
210
+ <div key={label} className="flex items-center gap-2 rounded-lg bg-gray-50 px-3 py-1.5">
211
211
  <span className="text-sm font-medium text-gray-800">{label}</span>
212
- <span className="px-2 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
212
+ <span className="rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800">
213
213
  {count}
214
214
  </span>
215
215
  </div>
@@ -217,22 +217,22 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
217
217
  </div>
218
218
  </div>
219
219
 
220
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
221
- <div className="p-3 flex flex-col sm:flex-row gap-3">
222
- <div className="flex-1 relative">
223
- <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
220
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
221
+ <div className="flex flex-col gap-3 p-3 sm:flex-row">
222
+ <div className="relative flex-1">
223
+ <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
224
224
  <input
225
225
  type="text"
226
226
  placeholder="Search submissions..."
227
227
  value={searchQuery}
228
228
  onChange={(e) => setSearchQuery(e.target.value)}
229
- 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"
229
+ 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"
230
230
  />
231
231
  </div>
232
232
  <select
233
233
  value={filterStatus}
234
234
  onChange={(e) => setFilterStatus(e.target.value)}
235
- className="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
235
+ className="rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
236
236
  >
237
237
  <option value="all">All Status</option>
238
238
  <option value="new">New</option>
@@ -242,7 +242,7 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
242
242
  <select
243
243
  value={filterSource}
244
244
  onChange={(e) => setFilterSource(e.target.value)}
245
- className="px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
245
+ className="rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
246
246
  >
247
247
  <option value="all">All Sources</option>
248
248
  {uniqueSources.map((src) => (
@@ -255,7 +255,7 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
255
255
  </div>
256
256
 
257
257
  {filteredSubmissions.length === 0 ? (
258
- <div className="bg-white rounded-lg border border-gray-200 p-8 text-center">
258
+ <div className="rounded-lg border border-gray-200 bg-white p-8 text-center">
259
259
  <p className="text-sm text-gray-500">No submissions yet</p>
260
260
  </div>
261
261
  ) : (
@@ -268,56 +268,56 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
268
268
  return (
269
269
  <div
270
270
  key={submission.id}
271
- className="bg-white rounded-lg border border-gray-200 hover:shadow-md transition-shadow"
271
+ className="rounded-lg border border-gray-200 bg-white transition-shadow hover:shadow-md"
272
272
  >
273
273
  <div className="p-4">
274
- <div className="flex items-start justify-between mb-3">
275
- <div className="flex items-start gap-3 flex-1">
276
- <div className="w-10 h-10 bg-linear-to-br from-blue-500 to-purple-600 rounded-full flex items-center justify-center text-white font-medium shrink-0 text-sm">
274
+ <div className="mb-3 flex items-start justify-between">
275
+ <div className="flex flex-1 items-start gap-3">
276
+ <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-purple-600 text-sm font-medium text-white">
277
277
  {submission.name.charAt(0)}
278
278
  </div>
279
- <div className="flex-1 min-w-0">
280
- <div className="flex items-center gap-2 mb-1">
281
- <h3 className="font-semibold text-gray-900 text-sm">{submission.name}</h3>
279
+ <div className="min-w-0 flex-1">
280
+ <div className="mb-1 flex items-center gap-2">
281
+ <h3 className="text-sm font-semibold text-gray-900">{submission.name}</h3>
282
282
  <span
283
- className={`px-2 py-0.5 rounded-full text-xs font-medium ${submission.status === 'new' ? 'bg-blue-100 text-blue-800' : submission.status === 'read' ? 'bg-gray-100 text-gray-800' : 'bg-green-100 text-green-800'}`}
283
+ className={`rounded-full px-2 py-0.5 text-xs font-medium ${submission.status === 'new' ? 'bg-blue-100 text-blue-800' : submission.status === 'read' ? 'bg-gray-100 text-gray-800' : 'bg-green-100 text-green-800'}`}
284
284
  >
285
285
  {submission.status}
286
286
  </span>
287
287
  </div>
288
- <div className="text-xs text-gray-600 mb-2">
288
+ <div className="mb-2 text-xs text-gray-600">
289
289
  {submission.email}
290
290
  {submission.phone ? ` · ${submission.phone}` : ''}
291
291
  </div>
292
292
  <p className="text-sm text-gray-700">{submission.message}</p>
293
- <div className="text-xs text-gray-500 mt-2">
293
+ <div className="mt-2 text-xs text-gray-500">
294
294
  Submitted {submission.submittedAt}
295
295
  </div>
296
296
  </div>
297
297
  </div>
298
298
  <button
299
299
  onClick={() => toast.success('Submission deleted')}
300
- className="p-1.5 hover:bg-gray-100 rounded transition-colors"
300
+ className="rounded p-1.5 transition-colors hover:bg-gray-100"
301
301
  title="Delete"
302
302
  >
303
- <Trash2 className="w-4 h-4 text-red-600" />
303
+ <Trash2 className="h-4 w-4 text-red-600" />
304
304
  </button>
305
305
  </div>
306
306
 
307
- <div className="flex flex-wrap items-center gap-2 mt-3 pt-3 border-t border-gray-100">
307
+ <div className="mt-3 flex flex-wrap items-center gap-2 border-t border-gray-100 pt-3">
308
308
  <span
309
- className={`px-2 py-0.5 rounded-full text-xs font-medium ${sourceColor(attr.source)}`}
309
+ className={`rounded-full px-2 py-0.5 text-xs font-medium ${sourceColor(attr.source)}`}
310
310
  >
311
311
  {attr.source}
312
312
  </span>
313
- <span className="text-gray-400 text-xs">/</span>
313
+ <span className="text-xs text-gray-400">/</span>
314
314
  <span
315
- className={`px-2 py-0.5 rounded-full text-xs font-medium ${mediumColor(attr.medium)}`}
315
+ className={`rounded-full px-2 py-0.5 text-xs font-medium ${mediumColor(attr.medium)}`}
316
316
  >
317
317
  {attr.medium}
318
318
  </span>
319
319
  {attr.campaign && (
320
- <span className="px-2 py-0.5 rounded-full text-xs font-medium bg-amber-100 text-amber-800">
320
+ <span className="rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800">
321
321
  {attr.campaign}
322
322
  </span>
323
323
  )}
@@ -327,28 +327,28 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
327
327
  </span>
328
328
  {activeClickIds.length > 0 && (
329
329
  <span className="flex items-center gap-1 text-xs text-gray-500">
330
- <MousePointerClick className="w-3.5 h-3.5" />
330
+ <MousePointerClick className="h-3.5 w-3.5" />
331
331
  {activeClickIds.map(([k]) => k).join(', ')}
332
332
  </span>
333
333
  )}
334
334
  <button
335
335
  onClick={() => setExpandedId(expanded ? null : submission.id)}
336
- className="ml-auto flex items-center gap-1 text-xs text-blue-600 hover:text-blue-800 transition-colors"
336
+ className="ml-auto flex items-center gap-1 text-xs text-blue-600 transition-colors hover:text-blue-800"
337
337
  >
338
338
  {expanded ? (
339
- <ChevronUp className="w-3.5 h-3.5" />
339
+ <ChevronUp className="h-3.5 w-3.5" />
340
340
  ) : (
341
- <ChevronDown className="w-3.5 h-3.5" />
341
+ <ChevronDown className="h-3.5 w-3.5" />
342
342
  )}
343
343
  {expanded ? 'Hide' : 'Attribution'}
344
344
  </button>
345
345
  </div>
346
346
 
347
347
  {expanded && (
348
- <div className="mt-3 pt-3 border-t border-gray-100 bg-gray-50 rounded-lg p-4 text-sm space-y-4">
349
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
348
+ <div className="mt-3 space-y-4 rounded-lg border-t border-gray-100 bg-gray-50 p-4 pt-3 text-sm">
349
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
350
350
  <div>
351
- <h4 className="text-xs font-semibold text-gray-600 uppercase tracking-wider mb-2">
351
+ <h4 className="mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase">
352
352
  Traffic Source
353
353
  </h4>
354
354
  <div className="space-y-1.5">
@@ -381,25 +381,25 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
381
381
  </div>
382
382
  </div>
383
383
  <div>
384
- <h4 className="text-xs font-semibold text-gray-600 uppercase tracking-wider mb-2">
384
+ <h4 className="mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase">
385
385
  Page Context
386
386
  </h4>
387
387
  <div className="space-y-1.5">
388
388
  <div>
389
- <span className="text-gray-500 text-xs">Landing Page</span>
390
- <div className="flex items-center gap-1 mt-0.5">
391
- <MapPin className="w-3 h-3 text-gray-400 shrink-0" />
392
- <span className="font-medium text-gray-900 text-xs break-all">
389
+ <span className="text-xs text-gray-500">Landing Page</span>
390
+ <div className="mt-0.5 flex items-center gap-1">
391
+ <MapPin className="h-3 w-3 shrink-0 text-gray-400" />
392
+ <span className="text-xs font-medium break-all text-gray-900">
393
393
  {attr.landingPage}
394
394
  </span>
395
395
  </div>
396
396
  </div>
397
397
  {attr.referrer && (
398
398
  <div>
399
- <span className="text-gray-500 text-xs">Referrer</span>
400
- <div className="flex items-center gap-1 mt-0.5">
401
- <ExternalLink className="w-3 h-3 text-gray-400 shrink-0" />
402
- <span className="font-medium text-gray-900 text-xs break-all">
399
+ <span className="text-xs text-gray-500">Referrer</span>
400
+ <div className="mt-0.5 flex items-center gap-1">
401
+ <ExternalLink className="h-3 w-3 shrink-0 text-gray-400" />
402
+ <span className="text-xs font-medium break-all text-gray-900">
403
403
  {attr.referrer}
404
404
  </span>
405
405
  </div>
@@ -417,17 +417,17 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
417
417
  </div>
418
418
  {activeClickIds.length > 0 && (
419
419
  <div>
420
- <h4 className="text-xs font-semibold text-gray-600 uppercase tracking-wider mb-2">
420
+ <h4 className="mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase">
421
421
  Click IDs
422
422
  </h4>
423
423
  <div className="flex flex-wrap gap-2">
424
424
  {activeClickIds.map(([key, val]) => (
425
425
  <div
426
426
  key={key}
427
- className="px-2.5 py-1 bg-white border border-gray-200 rounded-lg"
427
+ className="rounded-lg border border-gray-200 bg-white px-2.5 py-1"
428
428
  >
429
429
  <span className="text-xs text-gray-500">{key}: </span>
430
- <span className="text-xs font-mono text-gray-800">
430
+ <span className="font-mono text-xs text-gray-800">
431
431
  {String(val).slice(0, 20)}...
432
432
  </span>
433
433
  </div>
@@ -442,11 +442,11 @@ export function FormSubmissions({ formId, onNavigate }: FormSubmissionsProps) {
442
442
  )}
443
443
  </div>
444
444
 
445
- <div className="px-4 py-3 border-t border-gray-200 flex items-center gap-2">
446
- <button className="px-3 py-1.5 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
445
+ <div className="flex items-center gap-2 border-t border-gray-200 px-4 py-3">
446
+ <button className="rounded-lg bg-blue-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-blue-700">
447
447
  Reply
448
448
  </button>
449
- <button className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors">
449
+ <button className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50">
450
450
  Mark as Read
451
451
  </button>
452
452
  </div>
@@ -30,8 +30,8 @@ export function Forms({ onNavigate }: FormsProps) {
30
30
 
31
31
  if (loading) {
32
32
  return (
33
- <div className="p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64">
34
- <Loader2 className="w-6 h-6 animate-spin text-blue-600" />
33
+ <div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
34
+ <Loader2 className="h-6 w-6 animate-spin text-blue-600" />
35
35
  </div>
36
36
  )
37
37
  }
@@ -40,89 +40,89 @@ export function Forms({ onNavigate }: FormsProps) {
40
40
  <div className="p-3 pr-6 sm:p-4 sm:pr-8">
41
41
  {error && (
42
42
  <div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
43
- <AlertTriangle className="w-5 h-5 text-red-600 shrink-0" />
44
- <span className="text-sm text-red-800 flex-1">{error}</span>
43
+ <AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
44
+ <span className="flex-1 text-sm text-red-800">{error}</span>
45
45
  <button
46
46
  onClick={refetch}
47
- className="px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors"
47
+ className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
48
48
  >
49
49
  Retry
50
50
  </button>
51
51
  </div>
52
52
  )}
53
53
 
54
- <div className="flex items-center justify-between mb-4">
54
+ <div className="mb-4 flex items-center justify-between">
55
55
  <div>
56
- <h1 className="text-xl sm:text-2xl font-semibold text-gray-900 mb-1">Forms</h1>
56
+ <h1 className="mb-1 text-xl font-semibold text-gray-900 sm:text-2xl">Forms</h1>
57
57
  <p className="text-sm text-gray-600">{filteredAndSorted.length} total forms</p>
58
58
  </div>
59
59
  <button
60
60
  onClick={() => onNavigate?.('/forms/new')}
61
- 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"
61
+ 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"
62
62
  >
63
- <Plus className="w-4 h-4" />
63
+ <Plus className="h-4 w-4" />
64
64
  New Form
65
65
  </button>
66
66
  </div>
67
67
 
68
- <div className="bg-white rounded-lg border border-gray-200 mb-4">
68
+ <div className="mb-4 rounded-lg border border-gray-200 bg-white">
69
69
  <div className="p-3">
70
70
  <div className="relative">
71
- <Search className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" />
71
+ <Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
72
72
  <input
73
73
  type="text"
74
74
  placeholder="Search forms..."
75
75
  value={searchQuery}
76
76
  onChange={(e) => setSearchQuery(e.target.value)}
77
- 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"
77
+ 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"
78
78
  />
79
79
  </div>
80
80
  </div>
81
81
  </div>
82
82
 
83
83
  {filteredAndSorted.length === 0 ? (
84
- <div className="bg-white rounded-lg border border-gray-200 p-8 text-center">
85
- <p className="text-sm text-gray-500 mb-2">No forms yet</p>
86
- <button className="px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">
84
+ <div className="rounded-lg border border-gray-200 bg-white p-8 text-center">
85
+ <p className="mb-2 text-sm text-gray-500">No forms yet</p>
86
+ <button className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700">
87
87
  Create your first form
88
88
  </button>
89
89
  </div>
90
90
  ) : (
91
- <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
91
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
92
92
  {filteredAndSorted.map((form: any) => (
93
93
  <div
94
94
  key={form.id}
95
- className="bg-white rounded-lg border border-gray-200 p-4 hover:shadow-md transition-shadow"
95
+ className="rounded-lg border border-gray-200 bg-white p-4 transition-shadow hover:shadow-md"
96
96
  >
97
- <div className="flex items-start justify-between mb-3">
97
+ <div className="mb-3 flex items-start justify-between">
98
98
  <div className="flex-1">
99
- <h3 className="font-semibold text-gray-900 mb-1">{form.name}</h3>
100
- <p className="text-sm text-gray-600 mb-2">{form.description}</p>
99
+ <h3 className="mb-1 font-semibold text-gray-900">{form.name}</h3>
100
+ <p className="mb-2 text-sm text-gray-600">{form.description}</p>
101
101
  </div>
102
- <button className="p-1.5 hover:bg-gray-100 rounded transition-colors">
103
- <MoreVertical className="w-4 h-4 text-gray-600" />
102
+ <button className="rounded p-1.5 transition-colors hover:bg-gray-100">
103
+ <MoreVertical className="h-4 w-4 text-gray-600" />
104
104
  </button>
105
105
  </div>
106
- <div className="flex items-center gap-4 text-sm text-gray-600 mb-3">
106
+ <div className="mb-3 flex items-center gap-4 text-sm text-gray-600">
107
107
  <span className="flex items-center gap-1">
108
- <FileText className="w-4 h-4" />
108
+ <FileText className="h-4 w-4" />
109
109
  {form.fields} fields
110
110
  </span>
111
111
  <span className="flex items-center gap-1">
112
- <Send className="w-4 h-4" />
112
+ <Send className="h-4 w-4" />
113
113
  {form.submissions} submissions
114
114
  </span>
115
115
  </div>
116
116
  <div className="flex items-center gap-2">
117
117
  <button
118
118
  onClick={() => onNavigate?.(`/forms/${form.id}/submissions`)}
119
- className="flex-1 px-3 py-1.5 text-sm text-center bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
119
+ className="flex-1 rounded-lg bg-blue-600 px-3 py-1.5 text-center text-sm text-white transition-colors hover:bg-blue-700"
120
120
  >
121
121
  View Submissions
122
122
  </button>
123
123
  <button
124
124
  onClick={() => onNavigate?.(`/forms/${form.id}/edit`)}
125
- className="px-3 py-1.5 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors"
125
+ className="rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50"
126
126
  >
127
127
  Edit
128
128
  </button>