@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
@@ -1,7 +1,18 @@
1
1
  'use client'
2
2
 
3
3
  import { useState, useEffect, useCallback, useRef } from 'react'
4
- import { AlertTriangle, Eye, EyeOff, Save, Copy, Loader2, Clock } from 'lucide-react'
4
+ import {
5
+ AlertTriangle,
6
+ Calendar,
7
+ Eye,
8
+ EyeOff,
9
+ Save,
10
+ Copy,
11
+ Loader2,
12
+ Clock,
13
+ Share2,
14
+ XCircle,
15
+ } from 'lucide-react'
5
16
  import { toast } from 'sonner'
6
17
  import { FieldRenderer } from '../fields/FieldRenderer.js'
7
18
  import { RelationshipField } from '../fields/RelationshipField.js'
@@ -12,6 +23,8 @@ import { VersionHistory } from '../components/VersionHistory.js'
12
23
  import { PresenceIndicator } from '../components/PresenceIndicator.js'
13
24
  import { SEOPanel } from '../components/SEOPanel.js'
14
25
  import type { SEOData } from '../components/SEOPanel.js'
26
+ import { SchedulePublishDialog } from '../components/SchedulePublishDialog.js'
27
+ import { SharePreviewLinkDialog } from '../components/SharePreviewLinkDialog.js'
15
28
  import { cmsApi } from '../lib/api.js'
16
29
 
17
30
  export interface DocumentEditProps {
@@ -40,7 +53,11 @@ export function DocumentEdit({
40
53
  const [loading, setLoading] = useState(!isNew)
41
54
  const [showPreview, setShowPreview] = useState(false)
42
55
  const [showVersions, setShowVersions] = useState(false)
56
+ const [showSchedule, setShowSchedule] = useState(false)
57
+ const [showShareLink, setShowShareLink] = useState(false)
43
58
  const [docStatus, setDocStatus] = useState<string>('DRAFT')
59
+ const [scheduledAt, setScheduledAt] = useState<string | null>(null)
60
+ const [scheduledUnpublishAt, setScheduledUnpublishAt] = useState<string | null>(null)
44
61
  const hasLoadedRef = useRef(false)
45
62
 
46
63
  const collections = config?.collections
@@ -125,6 +142,8 @@ export function DocumentEdit({
125
142
  setValues(merged)
126
143
  setInitialValues(merged)
127
144
  setDocStatus(doc.status ?? 'DRAFT')
145
+ setScheduledAt(doc.scheduledAt ?? null)
146
+ setScheduledUnpublishAt(doc.scheduledUnpublishAt ?? null)
128
147
 
129
148
  const loadedSeo: SEOData = {}
130
149
  for (const key of SEO_FIELDS) {
@@ -279,8 +298,8 @@ export function DocumentEdit({
279
298
 
280
299
  if (loading) {
281
300
  return (
282
- <div className="flex items-center justify-center min-h-[300px]">
283
- <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" />
284
303
  </div>
285
304
  )
286
305
  }
@@ -291,12 +310,12 @@ export function DocumentEdit({
291
310
  <div className="flex items-center gap-3">
292
311
  <h1 className="text-2xl font-bold">{displayTitle}</h1>
293
312
  <span
294
- 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}`}
295
314
  >
296
315
  {docStatus}
297
316
  </span>
298
317
  {documentId && <PresenceIndicator documentId={documentId} />}
299
- {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>}
300
319
  </div>
301
320
  <div className="flex items-center gap-2">
302
321
  <button
@@ -309,6 +328,14 @@ export function DocumentEdit({
309
328
  </button>
310
329
  {!isNew && (
311
330
  <>
331
+ <button
332
+ onClick={() => setShowShareLink(true)}
333
+ className="inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]"
334
+ title="Share a signed preview link for the current draft"
335
+ >
336
+ <Share2 className="h-4 w-4" />
337
+ Share preview
338
+ </button>
312
339
  <button
313
340
  onClick={() => setShowVersions(true)}
314
341
  className="inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]"
@@ -333,11 +360,11 @@ export function DocumentEdit({
333
360
  <div className={showPreview ? 'grid grid-cols-2 gap-6' : ''}>
334
361
  <div className="space-y-6">
335
362
  {fields.length === 0 ? (
336
- <div className="flex flex-col items-center justify-center py-16 text-center rounded-lg border border-[var(--border)]">
337
- <div className="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-4">
338
- <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" />
339
366
  </div>
340
- <h3 className="text-sm font-medium text-gray-900 mb-1">
367
+ <h3 className="mb-1 text-sm font-medium text-gray-900">
341
368
  Collection schema not found
342
369
  </h3>
343
370
  <p className="text-sm text-gray-500">No fields are defined for this collection.</p>
@@ -379,6 +406,31 @@ export function DocumentEdit({
379
406
  Unpublish
380
407
  </Button>
381
408
  )}
409
+ {!isNew && (
410
+ <button
411
+ onClick={() => setShowSchedule(true)}
412
+ className="inline-flex w-full items-center justify-center gap-1.5 rounded-md border border-[var(--border)] bg-white px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50"
413
+ >
414
+ <Calendar className="h-4 w-4" />
415
+ {scheduledAt || scheduledUnpublishAt ? 'Reschedule' : 'Schedule'}
416
+ </button>
417
+ )}
418
+ {!isNew && (scheduledAt || scheduledUnpublishAt) && (
419
+ <div className="space-y-1 rounded-md border border-blue-100 bg-blue-50 px-3 py-2 text-xs text-blue-900">
420
+ {scheduledAt && (
421
+ <div className="flex items-center gap-1.5">
422
+ <Calendar className="h-3.5 w-3.5" />
423
+ Publishes {new Date(scheduledAt).toLocaleString()}
424
+ </div>
425
+ )}
426
+ {scheduledUnpublishAt && (
427
+ <div className="flex items-center gap-1.5">
428
+ <XCircle className="h-3.5 w-3.5" />
429
+ Unpublishes {new Date(scheduledUnpublishAt).toLocaleString()}
430
+ </div>
431
+ )}
432
+ </div>
433
+ )}
382
434
  </div>
383
435
  </div>
384
436
 
@@ -465,7 +517,7 @@ export function DocumentEdit({
465
517
  Cancel
466
518
  </Button>
467
519
  <Button variant="primary" loading={saving} onClick={handleSave} data-shortcut="save">
468
- <Save className="h-4 w-4 mr-1.5" />
520
+ <Save className="mr-1.5 h-4 w-4" />
469
521
  {isNew ? 'Create' : 'Save Changes'}
470
522
  </Button>
471
523
  </div>
@@ -495,6 +547,34 @@ export function DocumentEdit({
495
547
  }}
496
548
  />
497
549
  )}
550
+
551
+ {!isNew && documentId && (
552
+ <SchedulePublishDialog
553
+ collectionSlug={collectionSlug}
554
+ documentId={documentId}
555
+ scheduledAt={scheduledAt}
556
+ scheduledUnpublishAt={scheduledUnpublishAt}
557
+ open={showSchedule}
558
+ onClose={() => setShowSchedule(false)}
559
+ onScheduled={(next) => {
560
+ setDocStatus(next.status)
561
+ setScheduledAt(next.scheduledAt)
562
+ setScheduledUnpublishAt(next.scheduledUnpublishAt)
563
+ }}
564
+ />
565
+ )}
566
+
567
+ {!isNew && documentId && (
568
+ <SharePreviewLinkDialog
569
+ collectionSlug={collectionSlug}
570
+ documentId={documentId}
571
+ documentSlug={docSlug}
572
+ siteUrl={config?.siteUrl}
573
+ urlPrefix={collection?.urlPrefix ?? collectionSlug}
574
+ open={showShareLink}
575
+ onClose={() => setShowShareLink(false)}
576
+ />
577
+ )}
498
578
  </div>
499
579
  )
500
580
  }
@@ -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
  )}