@actuate-media/cms-admin 0.10.0 → 0.12.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 (315) hide show
  1. package/LICENSE +21 -21
  2. package/dist/AdminRoot.d.ts.map +1 -1
  3. package/dist/AdminRoot.js +8 -5
  4. package/dist/AdminRoot.js.map +1 -1
  5. package/dist/__tests__/fields/component-block-helpers.test.d.ts +7 -0
  6. package/dist/__tests__/fields/component-block-helpers.test.d.ts.map +1 -0
  7. package/dist/__tests__/fields/component-block-helpers.test.js +592 -0
  8. package/dist/__tests__/fields/component-block-helpers.test.js.map +1 -0
  9. package/dist/__tests__/layout/primitives.test.d.ts +2 -0
  10. package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
  11. package/dist/__tests__/layout/primitives.test.js +34 -0
  12. package/dist/__tests__/layout/primitives.test.js.map +1 -0
  13. package/dist/__tests__/lib/cv.test.d.ts +2 -0
  14. package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
  15. package/dist/__tests__/lib/cv.test.js +66 -0
  16. package/dist/__tests__/lib/cv.test.js.map +1 -0
  17. package/dist/actuate-admin.css +1 -1
  18. package/dist/assets/actuate-logo.d.ts +36 -0
  19. package/dist/assets/actuate-logo.d.ts.map +1 -0
  20. package/dist/assets/actuate-logo.js +15 -0
  21. package/dist/assets/actuate-logo.js.map +1 -0
  22. package/dist/components/Breadcrumbs.js +2 -2
  23. package/dist/components/CommandPalette.js +10 -10
  24. package/dist/components/ContentOverviewChart.js +3 -3
  25. package/dist/components/ErrorBoundary.js +1 -1
  26. package/dist/components/FocalPointPicker.js +2 -2
  27. package/dist/components/FolderTree.js +20 -20
  28. package/dist/components/LivePreview.js +3 -3
  29. package/dist/components/LocaleSwitcher.js +1 -1
  30. package/dist/components/MediaPickerModal.js +4 -4
  31. package/dist/components/PresenceIndicator.js +1 -1
  32. package/dist/components/SEOConfigPanel.d.ts +2 -0
  33. package/dist/components/SEOConfigPanel.d.ts.map +1 -0
  34. package/dist/components/SEOConfigPanel.js +174 -0
  35. package/dist/components/SEOConfigPanel.js.map +1 -0
  36. package/dist/components/SEOPanel.js +9 -9
  37. package/dist/components/SEOPerformance.js +2 -2
  38. package/dist/components/SchedulePublishDialog.js +1 -1
  39. package/dist/components/SharePreviewLinkDialog.js +1 -1
  40. package/dist/components/TipTapEditor.js +5 -5
  41. package/dist/components/VersionHistory.js +2 -2
  42. package/dist/components/ui/Badge.d.ts +33 -3
  43. package/dist/components/ui/Badge.d.ts.map +1 -1
  44. package/dist/components/ui/Badge.js +42 -8
  45. package/dist/components/ui/Badge.js.map +1 -1
  46. package/dist/components/ui/Button.d.ts +19 -8
  47. package/dist/components/ui/Button.d.ts.map +1 -1
  48. package/dist/components/ui/Button.js +35 -14
  49. package/dist/components/ui/Button.js.map +1 -1
  50. package/dist/components/ui/Card.d.ts +26 -0
  51. package/dist/components/ui/Card.d.ts.map +1 -0
  52. package/dist/components/ui/Card.js +45 -0
  53. package/dist/components/ui/Card.js.map +1 -0
  54. package/dist/components/ui/DataTable.js +1 -1
  55. package/dist/components/ui/Input.d.ts +15 -0
  56. package/dist/components/ui/Input.d.ts.map +1 -0
  57. package/dist/components/ui/Input.js +23 -0
  58. package/dist/components/ui/Input.js.map +1 -0
  59. package/dist/components/ui/SearchInput.js +1 -1
  60. package/dist/components/ui/Select.d.ts +16 -0
  61. package/dist/components/ui/Select.d.ts.map +1 -0
  62. package/dist/components/ui/Select.js +25 -0
  63. package/dist/components/ui/Select.js.map +1 -0
  64. package/dist/components/ui/Toast.js +1 -1
  65. package/dist/components/ui/index.d.ts +10 -4
  66. package/dist/components/ui/index.d.ts.map +1 -1
  67. package/dist/components/ui/index.js +5 -2
  68. package/dist/components/ui/index.js.map +1 -1
  69. package/dist/fields/BlockBuilderField.js +3 -3
  70. package/dist/fields/ComponentBlockField.d.ts +25 -0
  71. package/dist/fields/ComponentBlockField.d.ts.map +1 -0
  72. package/dist/fields/ComponentBlockField.js +74 -0
  73. package/dist/fields/ComponentBlockField.js.map +1 -0
  74. package/dist/fields/DateField.js +1 -1
  75. package/dist/fields/FieldRenderer.d.ts +3 -0
  76. package/dist/fields/FieldRenderer.d.ts.map +1 -1
  77. package/dist/fields/FieldRenderer.js +3 -1
  78. package/dist/fields/FieldRenderer.js.map +1 -1
  79. package/dist/fields/PropInput.d.ts +14 -0
  80. package/dist/fields/PropInput.d.ts.map +1 -0
  81. package/dist/fields/PropInput.js +163 -0
  82. package/dist/fields/PropInput.js.map +1 -0
  83. package/dist/fields/RelationshipField.js +3 -3
  84. package/dist/fields/TextField.js +1 -1
  85. package/dist/fields/component-block-helpers.d.ts +96 -0
  86. package/dist/fields/component-block-helpers.d.ts.map +1 -0
  87. package/dist/fields/component-block-helpers.js +323 -0
  88. package/dist/fields/component-block-helpers.js.map +1 -0
  89. package/dist/fields/index.d.ts +4 -0
  90. package/dist/fields/index.d.ts.map +1 -1
  91. package/dist/fields/index.js +2 -0
  92. package/dist/fields/index.js.map +1 -1
  93. package/dist/index.d.ts +4 -0
  94. package/dist/index.d.ts.map +1 -1
  95. package/dist/index.js +4 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/layout/Header.js +1 -1
  98. package/dist/layout/Layout.d.ts +14 -0
  99. package/dist/layout/Layout.d.ts.map +1 -1
  100. package/dist/layout/Layout.js +17 -11
  101. package/dist/layout/Layout.js.map +1 -1
  102. package/dist/layout/Sidebar.d.ts.map +1 -1
  103. package/dist/layout/Sidebar.js +21 -11
  104. package/dist/layout/Sidebar.js.map +1 -1
  105. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  106. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  107. package/dist/layout/primitives/AdminShell.js +51 -0
  108. package/dist/layout/primitives/AdminShell.js.map +1 -0
  109. package/dist/layout/primitives/Box.d.ts +19 -0
  110. package/dist/layout/primitives/Box.d.ts.map +1 -0
  111. package/dist/layout/primitives/Box.js +12 -0
  112. package/dist/layout/primitives/Box.js.map +1 -0
  113. package/dist/layout/primitives/Cluster.d.ts +27 -0
  114. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  115. package/dist/layout/primitives/Cluster.js +37 -0
  116. package/dist/layout/primitives/Cluster.js.map +1 -0
  117. package/dist/layout/primitives/Grid.d.ts +45 -0
  118. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  119. package/dist/layout/primitives/Grid.js +59 -0
  120. package/dist/layout/primitives/Grid.js.map +1 -0
  121. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  122. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  123. package/dist/layout/primitives/PageContainer.js +41 -0
  124. package/dist/layout/primitives/PageContainer.js.map +1 -0
  125. package/dist/layout/primitives/Split.d.ts +34 -0
  126. package/dist/layout/primitives/Split.d.ts.map +1 -0
  127. package/dist/layout/primitives/Split.js +27 -0
  128. package/dist/layout/primitives/Split.js.map +1 -0
  129. package/dist/layout/primitives/Stack.d.ts +23 -0
  130. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  131. package/dist/layout/primitives/Stack.js +34 -0
  132. package/dist/layout/primitives/Stack.js.map +1 -0
  133. package/dist/layout/primitives/index.d.ts +30 -0
  134. package/dist/layout/primitives/index.d.ts.map +1 -0
  135. package/dist/layout/primitives/index.js +22 -0
  136. package/dist/layout/primitives/index.js.map +1 -0
  137. package/dist/layout/primitives/tokens.d.ts +48 -0
  138. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  139. package/dist/layout/primitives/tokens.js +54 -0
  140. package/dist/layout/primitives/tokens.js.map +1 -0
  141. package/dist/lib/cv.d.ts +53 -0
  142. package/dist/lib/cv.d.ts.map +1 -0
  143. package/dist/lib/cv.js +39 -0
  144. package/dist/lib/cv.js.map +1 -0
  145. package/dist/views/ApiKeys.js +7 -7
  146. package/dist/views/CollectionList.js +8 -8
  147. package/dist/views/Dashboard.d.ts.map +1 -1
  148. package/dist/views/Dashboard.js +333 -78
  149. package/dist/views/Dashboard.js.map +1 -1
  150. package/dist/views/DocumentEdit.js +3 -3
  151. package/dist/views/ForgotPassword.js +2 -2
  152. package/dist/views/FormEditor.js +5 -5
  153. package/dist/views/FormSubmissions.js +6 -6
  154. package/dist/views/Forms.js +2 -2
  155. package/dist/views/Login.d.ts +16 -1
  156. package/dist/views/Login.d.ts.map +1 -1
  157. package/dist/views/Login.js +17 -7
  158. package/dist/views/Login.js.map +1 -1
  159. package/dist/views/MediaBrowser.js +16 -16
  160. package/dist/views/PageEditor.js +2 -2
  161. package/dist/views/Pages.js +10 -10
  162. package/dist/views/PostEditor.js +2 -2
  163. package/dist/views/Posts.js +4 -4
  164. package/dist/views/Redirects.js +4 -4
  165. package/dist/views/ResetPassword.js +2 -2
  166. package/dist/views/SEO.js +6 -6
  167. package/dist/views/ScriptTagEditor.js +4 -4
  168. package/dist/views/ScriptTags.js +2 -2
  169. package/dist/views/Settings.d.ts.map +1 -1
  170. package/dist/views/Settings.js +9 -8
  171. package/dist/views/Settings.js.map +1 -1
  172. package/dist/views/SetupWizard.js +2 -2
  173. package/dist/views/Users.js +4 -4
  174. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  175. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  176. package/dist/views/page-builder/BlockEditor.js +10 -10
  177. package/dist/views/page-builder/BlockPicker.js +4 -4
  178. package/dist/views/page-builder/BottomBar.js +1 -1
  179. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  180. package/dist/views/page-builder/ContextPanel.js +2 -2
  181. package/dist/views/page-builder/DesignScore.js +9 -9
  182. package/dist/views/page-builder/NodeSettings.js +8 -8
  183. package/dist/views/page-builder/PageBuilder.js +3 -3
  184. package/dist/views/page-builder/PageSettings.js +1 -1
  185. package/dist/views/page-builder/PageTemplates.js +2 -2
  186. package/dist/views/page-builder/SEOPanel.js +13 -13
  187. package/dist/views/page-builder/SavedSections.js +5 -5
  188. package/dist/views/page-builder/TemplatePicker.js +2 -2
  189. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  190. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  191. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  192. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  193. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  194. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  195. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  196. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  197. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  198. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  199. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  200. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  201. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  202. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  203. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  204. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  205. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  206. package/package.json +14 -3
  207. package/src/AdminRoot.tsx +21 -11
  208. package/src/__tests__/fields/component-block-helpers.test.ts +674 -0
  209. package/src/__tests__/layout/primitives.test.ts +37 -0
  210. package/src/__tests__/lib/cv.test.ts +74 -0
  211. package/src/assets/actuate-logo.tsx +72 -0
  212. package/src/components/Breadcrumbs.tsx +6 -6
  213. package/src/components/CommandPalette.tsx +34 -34
  214. package/src/components/ContentOverviewChart.tsx +3 -3
  215. package/src/components/ErrorBoundary.tsx +3 -3
  216. package/src/components/FocalPointPicker.tsx +4 -4
  217. package/src/components/FolderTree.tsx +38 -38
  218. package/src/components/LivePreview.tsx +16 -16
  219. package/src/components/LocaleSwitcher.tsx +7 -7
  220. package/src/components/MediaPickerModal.tsx +21 -21
  221. package/src/components/PresenceIndicator.tsx +2 -2
  222. package/src/components/SEOConfigPanel.tsx +582 -0
  223. package/src/components/SEOPanel.tsx +46 -46
  224. package/src/components/SEOPerformance.tsx +21 -21
  225. package/src/components/SchedulePublishDialog.tsx +4 -4
  226. package/src/components/SharePreviewLinkDialog.tsx +1 -1
  227. package/src/components/TipTapEditor.tsx +33 -33
  228. package/src/components/VersionHistory.tsx +16 -16
  229. package/src/components/ui/Badge.tsx +66 -14
  230. package/src/components/ui/Button.tsx +70 -33
  231. package/src/components/ui/Card.tsx +101 -0
  232. package/src/components/ui/DataTable.tsx +1 -1
  233. package/src/components/ui/Input.tsx +35 -0
  234. package/src/components/ui/SearchInput.tsx +4 -4
  235. package/src/components/ui/Select.tsx +56 -0
  236. package/src/components/ui/Toast.tsx +1 -1
  237. package/src/components/ui/index.ts +18 -4
  238. package/src/fields/BlockBuilderField.tsx +3 -3
  239. package/src/fields/ComponentBlockField.tsx +179 -0
  240. package/src/fields/DateField.tsx +1 -1
  241. package/src/fields/FieldRenderer.tsx +8 -0
  242. package/src/fields/PropInput.tsx +552 -0
  243. package/src/fields/RelationshipField.tsx +10 -10
  244. package/src/fields/TextField.tsx +1 -1
  245. package/src/fields/component-block-helpers.ts +341 -0
  246. package/src/fields/index.ts +4 -0
  247. package/src/index.ts +35 -0
  248. package/src/layout/Header.tsx +28 -28
  249. package/src/layout/Layout.tsx +39 -46
  250. package/src/layout/Sidebar.tsx +37 -64
  251. package/src/layout/primitives/AdminShell.tsx +118 -0
  252. package/src/layout/primitives/Box.tsx +30 -0
  253. package/src/layout/primitives/Cluster.tsx +74 -0
  254. package/src/layout/primitives/Grid.tsx +120 -0
  255. package/src/layout/primitives/PageContainer.tsx +96 -0
  256. package/src/layout/primitives/Split.tsx +73 -0
  257. package/src/layout/primitives/Stack.tsx +67 -0
  258. package/src/layout/primitives/index.ts +36 -0
  259. package/src/layout/primitives/tokens.ts +76 -0
  260. package/src/lib/cv.ts +96 -0
  261. package/src/styles/build-input.css +1 -1
  262. package/src/views/ApiKeys.tsx +57 -57
  263. package/src/views/CollectionList.tsx +30 -30
  264. package/src/views/Dashboard.tsx +737 -186
  265. package/src/views/DocumentEdit.tsx +9 -9
  266. package/src/views/ForgotPassword.tsx +18 -18
  267. package/src/views/FormEditor.tsx +75 -75
  268. package/src/views/FormSubmissions.tsx +76 -76
  269. package/src/views/Forms.tsx +27 -27
  270. package/src/views/Login.tsx +65 -25
  271. package/src/views/MediaBrowser.tsx +127 -127
  272. package/src/views/PageEditor.tsx +25 -25
  273. package/src/views/Pages.tsx +59 -59
  274. package/src/views/PostEditor.tsx +37 -37
  275. package/src/views/Posts.tsx +48 -48
  276. package/src/views/Redirects.tsx +21 -21
  277. package/src/views/ResetPassword.tsx +28 -28
  278. package/src/views/SEO.tsx +144 -144
  279. package/src/views/ScriptTagEditor.tsx +24 -24
  280. package/src/views/ScriptTags.tsx +10 -10
  281. package/src/views/Settings.tsx +88 -80
  282. package/src/views/SetupWizard.tsx +28 -28
  283. package/src/views/Users.tsx +20 -20
  284. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  285. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  286. package/src/views/page-builder/BlockEditor.tsx +26 -26
  287. package/src/views/page-builder/BlockPicker.tsx +22 -22
  288. package/src/views/page-builder/BottomBar.tsx +8 -8
  289. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  290. package/src/views/page-builder/ContextPanel.tsx +3 -3
  291. package/src/views/page-builder/DesignScore.tsx +21 -21
  292. package/src/views/page-builder/NodeSettings.tsx +27 -27
  293. package/src/views/page-builder/PageBuilder.tsx +11 -11
  294. package/src/views/page-builder/PageSettings.tsx +4 -4
  295. package/src/views/page-builder/PageTemplates.tsx +18 -18
  296. package/src/views/page-builder/SEOPanel.tsx +53 -53
  297. package/src/views/page-builder/SavedSections.tsx +37 -37
  298. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  299. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  300. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  301. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  302. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  303. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  304. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  305. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  306. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  307. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  308. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  309. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  310. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  311. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  312. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  313. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  314. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  315. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -324,16 +324,16 @@ function ScoreRing({ score }) {
324
324
  return (_jsxs("div", { className: "relative inline-flex items-center justify-center", children: [_jsxs("svg", { width: "72", height: "72", className: "-rotate-90", children: [_jsx("circle", { cx: "36", cy: "36", r: radius, fill: "none", stroke: "var(--border)", strokeWidth: "5" }), _jsx("circle", { cx: "36", cy: "36", r: radius, fill: "none", stroke: color, strokeWidth: "5", strokeDasharray: circumference, strokeDashoffset: offset, strokeLinecap: "round", className: "transition-all duration-500" })] }), _jsx("span", { className: "absolute text-sm font-bold", style: { color }, children: score })] }));
325
325
  }
326
326
  function Section({ id, title, icon, expanded, onToggle, children, badge, }) {
327
- return (_jsxs("div", { className: "border border-[var(--border)] rounded-lg overflow-hidden", children: [_jsxs("button", { onClick: () => onToggle(id), className: "flex items-center justify-between w-full px-4 py-2.5 text-left text-sm font-medium text-[var(--foreground)] hover:bg-[var(--muted)] transition-colors", children: [_jsxs("span", { className: "flex items-center gap-2", children: [icon, title, badge] }), expanded ? (_jsx(ChevronUp, { className: "h-4 w-4 text-[var(--muted-foreground)]" })) : (_jsx(ChevronDown, { className: "h-4 w-4 text-[var(--muted-foreground)]" }))] }), expanded && _jsx("div", { className: "px-4 pb-4 pt-1", children: children })] }));
327
+ return (_jsxs("div", { className: "overflow-hidden rounded-lg border border-[var(--border)]", children: [_jsxs("button", { onClick: () => onToggle(id), className: "flex w-full items-center justify-between px-4 py-2.5 text-left text-sm font-medium text-[var(--foreground)] transition-colors hover:bg-[var(--muted)]", children: [_jsxs("span", { className: "flex items-center gap-2", children: [icon, title, badge] }), expanded ? (_jsx(ChevronUp, { className: "h-4 w-4 text-[var(--muted-foreground)]" })) : (_jsx(ChevronDown, { className: "h-4 w-4 text-[var(--muted-foreground)]" }))] }), expanded && _jsx("div", { className: "px-4 pt-1 pb-4", children: children })] }));
328
328
  }
329
329
  function ToggleSwitch({ label, description, checked, onChange, }) {
330
- return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("label", { className: "text-sm font-medium text-[var(--foreground)]", children: label }), _jsx("p", { className: "text-xs text-[var(--muted-foreground)] mt-0.5", children: description })] }), _jsx("button", { type: "button", role: "switch", "aria-checked": checked, onClick: () => onChange(!checked), className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full transition-colors ${checked ? 'bg-[var(--primary)]' : 'bg-[var(--muted)]'}`, children: _jsx("span", { className: `pointer-events-none block h-5 w-5 rounded-full bg-white shadow-sm transition-transform mt-0.5 ${checked ? 'translate-x-[22px]' : 'translate-x-0.5'}` }) })] }));
330
+ return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("label", { className: "text-sm font-medium text-[var(--foreground)]", children: label }), _jsx("p", { className: "mt-0.5 text-xs text-[var(--muted-foreground)]", children: description })] }), _jsx("button", { type: "button", role: "switch", "aria-checked": checked, onClick: () => onChange(!checked), className: `relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full transition-colors ${checked ? 'bg-[var(--primary)]' : 'bg-[var(--muted)]'}`, children: _jsx("span", { className: `pointer-events-none mt-0.5 block h-5 w-5 rounded-full bg-white shadow-sm transition-transform ${checked ? 'translate-x-[22px]' : 'translate-x-0.5'}` }) })] }));
331
331
  }
332
332
  function InputField({ label, value, onChange, placeholder, type = 'text', charCount, charTarget, }) {
333
- return (_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-[var(--muted-foreground)] mb-1", children: label }), _jsx("input", { type: type, value: value, onChange: (e) => onChange(e.target.value), className: "w-full px-3 py-1.5 text-sm border border-[var(--border)] rounded-lg bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] placeholder:text-[var(--muted-foreground)]", placeholder: placeholder }), charCount !== undefined && charTarget && (_jsxs("p", { className: "text-xs mt-1 text-[var(--muted-foreground)]", children: [charCount, " chars ", charTarget] }))] }));
333
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-[var(--muted-foreground)]", children: label }), _jsx("input", { type: type, value: value, onChange: (e) => onChange(e.target.value), className: "w-full rounded-lg border border-[var(--border)] bg-[var(--background)] px-3 py-1.5 text-sm text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus:ring-2 focus:ring-[var(--primary)] focus:outline-none", placeholder: placeholder }), charCount !== undefined && charTarget && (_jsxs("p", { className: "mt-1 text-xs text-[var(--muted-foreground)]", children: [charCount, " chars ", charTarget] }))] }));
334
334
  }
335
335
  function TextareaField({ label, value, onChange, placeholder, rows = 3, charCount, charTarget, }) {
336
- return (_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-[var(--muted-foreground)] mb-1", children: label }), _jsx("textarea", { value: value, onChange: (e) => onChange(e.target.value), rows: rows, className: "w-full px-3 py-1.5 text-sm border border-[var(--border)] rounded-lg bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)] resize-none placeholder:text-[var(--muted-foreground)]", placeholder: placeholder }), charCount !== undefined && charTarget && (_jsxs("p", { className: "text-xs mt-1 text-[var(--muted-foreground)]", children: [charCount, " chars ", charTarget] }))] }));
336
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-[var(--muted-foreground)]", children: label }), _jsx("textarea", { value: value, onChange: (e) => onChange(e.target.value), rows: rows, className: "w-full resize-none rounded-lg border border-[var(--border)] bg-[var(--background)] px-3 py-1.5 text-sm text-[var(--foreground)] placeholder:text-[var(--muted-foreground)] focus:ring-2 focus:ring-[var(--primary)] focus:outline-none", placeholder: placeholder }), charCount !== undefined && charTarget && (_jsxs("p", { className: "mt-1 text-xs text-[var(--muted-foreground)]", children: [charCount, " chars ", charTarget] }))] }));
337
337
  }
338
338
  export function SEOPanel({ title, slug, content = '', seoData, onChange, siteUrl = 'https://example.com', }) {
339
339
  const [expandedSections, setExpandedSections] = useState(['analysis']);
@@ -366,12 +366,12 @@ export function SEOPanel({ title, slug, content = '', seoData, onChange, siteUrl
366
366
  : readability.fleschScore >= 30
367
367
  ? 'text-amber-500'
368
368
  : 'text-red-500';
369
- return (_jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--card)]", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-[var(--border)]", children: [_jsxs("h3", { className: "font-semibold text-[var(--foreground)] flex items-center gap-2 text-sm", children: [_jsx(Search, { className: "w-4 h-4" }), "SEO"] }), _jsxs("button", { onClick: () => update({ metaTitle: title, ogTitle: '', ogDescription: '' }), className: "text-xs text-[var(--primary)] hover:opacity-80 flex items-center gap-1", children: [_jsx(RefreshCw, { className: "w-3 h-3" }), "Reset"] })] }), _jsxs("div", { className: "flex items-center gap-4 px-4 py-3 border-b border-[var(--border)]", children: [_jsx(ScoreRing, { score: score }), _jsxs("div", { className: "text-xs text-[var(--muted-foreground)] space-y-0.5", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(CheckCircle2, { className: "h-3 w-3 text-green-500" }), " ", goodCount, " passed"] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-500" }), " ", okCount, " improvements"] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(XCircle, { className: "h-3 w-3 text-red-500" }), " ", badCount, " issues"] })] })] }), _jsxs("div", { className: "p-3 space-y-2", children: [_jsx(Section, { id: "analysis", title: "SEO Analysis", icon: _jsx(BarChart3, { className: "h-4 w-4" }), expanded: expandedSections.includes('analysis'), onToggle: toggleSection, badge: _jsxs("span", { className: "ml-1 inline-flex items-center rounded-full bg-[var(--muted)] px-2 py-0.5 text-[10px] font-medium text-[var(--muted-foreground)]", children: [goodCount, "/", checks.length] }), children: _jsx("div", { className: "space-y-1.5", children: checks.map((c) => (_jsxs("div", { className: "flex items-start gap-2 py-1", children: [_jsx(StatusDot, { status: c.status }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm text-[var(--foreground)] leading-snug", children: c.label }), _jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: c.detail })] })] }, c.id))) }) }), _jsxs(Section, { id: "readability", title: "Readability", icon: _jsx(BookOpen, { className: "h-4 w-4" }), expanded: expandedSections.includes('readability'), onToggle: toggleSection, children: [_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Flesch Score" }), _jsx("p", { className: `text-lg font-bold ${fleschColor}`, children: readability.fleschScore }), _jsx("p", { className: `text-[10px] ${fleschColor}`, children: fleschLabel })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Word Count" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.wordCount }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "words" })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Avg. Sentence" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.avgSentenceLength.toFixed(1) }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "words/sentence" })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Reading Time" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.readingTime }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "min" })] })] }), _jsxs("div", { className: "mt-3 flex items-center gap-2 text-xs text-[var(--muted-foreground)]", children: [_jsx("span", { children: "Passive voice est.:" }), _jsxs("span", { className: readability.passiveEstimate > 15
370
- ? 'text-amber-500 font-medium'
371
- : 'text-green-500 font-medium', children: [readability.passiveEstimate, "%"] })] })] }), _jsx(Section, { id: "basic", title: "Basic SEO", icon: _jsx(Target, { className: "h-4 w-4" }), expanded: expandedSections.includes('basic'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "Meta Title", value: metaTitle, onChange: (v) => update({ metaTitle: v }), placeholder: title || 'Enter meta title', charCount: metaTitle.length, charTarget: "(ideal: 30-60)" }), _jsx(TextareaField, { label: "Meta Description", value: metaDesc, onChange: (v) => update({ metaDescription: v }), placeholder: "Brief description for search engines", charCount: metaDesc.length, charTarget: "(ideal: 120-160)" }), _jsx(InputField, { label: "Focus Keyphrase", value: seoData.focusKeyphrase ?? '', onChange: (v) => update({ focusKeyphrase: v }), placeholder: "Primary keyword or phrase" }), _jsx(InputField, { label: "Canonical URL", value: seoData.canonical ?? '', onChange: (v) => update({ canonical: v }), placeholder: "https://example.com/canonical-url", type: "url" })] }) }), _jsx(Section, { id: "robots", title: "Robots Meta", icon: _jsx(EyeOff, { className: "h-4 w-4" }), expanded: expandedSections.includes('robots'), onToggle: toggleSection, children: _jsx("div", { className: "space-y-4", children: _jsxs("div", { children: [_jsx("label", { id: "robots-policy-label", className: "mb-1 block text-xs font-medium text-muted-foreground", children: "Robots Policy" }), _jsxs(Select.Root, { value: robotsPolicy, onValueChange: (value) => {
369
+ return (_jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--card)]", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-[var(--border)] px-4 py-3", children: [_jsxs("h3", { className: "flex items-center gap-2 text-sm font-semibold text-[var(--foreground)]", children: [_jsx(Search, { className: "h-4 w-4" }), "SEO"] }), _jsxs("button", { onClick: () => update({ metaTitle: title, ogTitle: '', ogDescription: '' }), className: "flex items-center gap-1 text-xs text-[var(--primary)] hover:opacity-80", children: [_jsx(RefreshCw, { className: "h-3 w-3" }), "Reset"] })] }), _jsxs("div", { className: "flex items-center gap-4 border-b border-[var(--border)] px-4 py-3", children: [_jsx(ScoreRing, { score: score }), _jsxs("div", { className: "space-y-0.5 text-xs text-[var(--muted-foreground)]", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(CheckCircle2, { className: "h-3 w-3 text-green-500" }), " ", goodCount, " passed"] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(AlertCircle, { className: "h-3 w-3 text-amber-500" }), " ", okCount, " improvements"] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(XCircle, { className: "h-3 w-3 text-red-500" }), " ", badCount, " issues"] })] })] }), _jsxs("div", { className: "space-y-2 p-3", children: [_jsx(Section, { id: "analysis", title: "SEO Analysis", icon: _jsx(BarChart3, { className: "h-4 w-4" }), expanded: expandedSections.includes('analysis'), onToggle: toggleSection, badge: _jsxs("span", { className: "ml-1 inline-flex items-center rounded-full bg-[var(--muted)] px-2 py-0.5 text-[10px] font-medium text-[var(--muted-foreground)]", children: [goodCount, "/", checks.length] }), children: _jsx("div", { className: "space-y-1.5", children: checks.map((c) => (_jsxs("div", { className: "flex items-start gap-2 py-1", children: [_jsx(StatusDot, { status: c.status }), _jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm leading-snug text-[var(--foreground)]", children: c.label }), _jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: c.detail })] })] }, c.id))) }) }), _jsxs(Section, { id: "readability", title: "Readability", icon: _jsx(BookOpen, { className: "h-4 w-4" }), expanded: expandedSections.includes('readability'), onToggle: toggleSection, children: [_jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Flesch Score" }), _jsx("p", { className: `text-lg font-bold ${fleschColor}`, children: readability.fleschScore }), _jsx("p", { className: `text-[10px] ${fleschColor}`, children: fleschLabel })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Word Count" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.wordCount }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "words" })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Avg. Sentence" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.avgSentenceLength.toFixed(1) }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "words/sentence" })] }), _jsxs("div", { className: "rounded-lg bg-[var(--muted)] p-2.5", children: [_jsx("p", { className: "text-xs text-[var(--muted-foreground)]", children: "Reading Time" }), _jsx("p", { className: "text-lg font-bold text-[var(--foreground)]", children: readability.readingTime }), _jsx("p", { className: "text-[10px] text-[var(--muted-foreground)]", children: "min" })] })] }), _jsxs("div", { className: "mt-3 flex items-center gap-2 text-xs text-[var(--muted-foreground)]", children: [_jsx("span", { children: "Passive voice est.:" }), _jsxs("span", { className: readability.passiveEstimate > 15
370
+ ? 'font-medium text-amber-500'
371
+ : 'font-medium text-green-500', children: [readability.passiveEstimate, "%"] })] })] }), _jsx(Section, { id: "basic", title: "Basic SEO", icon: _jsx(Target, { className: "h-4 w-4" }), expanded: expandedSections.includes('basic'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "Meta Title", value: metaTitle, onChange: (v) => update({ metaTitle: v }), placeholder: title || 'Enter meta title', charCount: metaTitle.length, charTarget: "(ideal: 30-60)" }), _jsx(TextareaField, { label: "Meta Description", value: metaDesc, onChange: (v) => update({ metaDescription: v }), placeholder: "Brief description for search engines", charCount: metaDesc.length, charTarget: "(ideal: 120-160)" }), _jsx(InputField, { label: "Focus Keyphrase", value: seoData.focusKeyphrase ?? '', onChange: (v) => update({ focusKeyphrase: v }), placeholder: "Primary keyword or phrase" }), _jsx(InputField, { label: "Canonical URL", value: seoData.canonical ?? '', onChange: (v) => update({ canonical: v }), placeholder: "https://example.com/canonical-url", type: "url" })] }) }), _jsx(Section, { id: "robots", title: "Robots Meta", icon: _jsx(EyeOff, { className: "h-4 w-4" }), expanded: expandedSections.includes('robots'), onToggle: toggleSection, children: _jsx("div", { className: "space-y-4", children: _jsxs("div", { children: [_jsx("label", { id: "robots-policy-label", className: "text-muted-foreground mb-1 block text-xs font-medium", children: "Robots Policy" }), _jsxs(Select.Root, { value: robotsPolicy, onValueChange: (value) => {
372
372
  const policy = value;
373
373
  update({ robotsPolicy: policy, ...robotsPolicyToBooleans(policy) });
374
- }, children: [_jsxs(Select.Trigger, { "aria-labelledby": "robots-policy-label", className: "flex w-full items-center justify-between rounded-lg border border-border bg-background px-3 py-1.5 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-primary", children: [_jsx(Select.Value, {}), _jsx(Select.Icon, { children: _jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" }) })] }), _jsx(Select.Portal, { children: _jsx(Select.Content, { className: "z-50 overflow-hidden rounded-lg border border-border bg-card shadow-md", children: _jsx(Select.Viewport, { className: "p-1", children: ROBOTS_POLICY_OPTIONS.map((option) => (_jsxs(Select.Item, { value: option.value, className: "relative flex cursor-pointer select-none items-center rounded-md py-1.5 pl-8 pr-3 text-sm text-foreground outline-none hover:bg-muted focus:bg-muted", children: [_jsx(Select.ItemIndicator, { className: "absolute left-2 inline-flex items-center", children: _jsx(Check, { className: "h-4 w-4" }) }), _jsx(Select.ItemText, { children: option.label })] }, option.value))) }) }) })] }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Use inheritance for most pages. Override only when a page needs different index/follow behavior." })] }) }) }), _jsx(Section, { id: "preview", title: "Search Preview", icon: _jsx(Globe, { className: "h-4 w-4" }), expanded: expandedSections.includes('preview'), onToggle: toggleSection, children: _jsxs("div", { className: "rounded-lg border border-[var(--border)] p-3 bg-[var(--background)]", children: [_jsx("div", { className: "text-sm text-blue-600 hover:underline cursor-pointer line-clamp-1", children: metaTitle || title || 'Page Title' }), _jsxs("div", { className: "text-xs text-green-700 mt-1 truncate", children: [siteUrl, "/", slug] }), _jsx("div", { className: "text-sm text-[var(--muted-foreground)] mt-1 line-clamp-2", children: metaDesc ||
375
- 'Add a meta description to see how this page will appear in search results.' })] }) }), _jsx(Section, { id: "social", title: "Social Media", icon: _jsx(Share2, { className: "h-4 w-4" }), expanded: expandedSections.includes('social'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "OG Title", value: seoData.ogTitle ?? '', onChange: (v) => update({ ogTitle: v }), placeholder: metaTitle || title || 'Leave blank to use meta title' }), _jsx(TextareaField, { label: "OG Description", value: seoData.ogDescription ?? '', onChange: (v) => update({ ogDescription: v }), rows: 2, placeholder: metaDesc || 'Leave blank to use meta description' }), _jsx(InputField, { label: "OG Image URL", value: seoData.ogImage ?? '', onChange: (v) => update({ ogImage: v }), placeholder: "https://example.com/og-image.jpg", type: "url" }), _jsxs("div", { className: "border-t border-[var(--border)] pt-3 mt-3", children: [_jsx("p", { className: "text-xs font-medium text-[var(--muted-foreground)] mb-2", children: "Twitter / X Overrides" }), _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "Twitter Title", value: seoData.twitterTitle ?? '', onChange: (v) => update({ twitterTitle: v }), placeholder: "Leave blank to use OG title" }), _jsx(TextareaField, { label: "Twitter Description", value: seoData.twitterDescription ?? '', onChange: (v) => update({ twitterDescription: v }), rows: 2, placeholder: "Leave blank to use OG description" }), _jsx(InputField, { label: "Twitter Image URL", value: seoData.twitterImage ?? '', onChange: (v) => update({ twitterImage: v }), placeholder: "Leave blank to use OG image", type: "url" })] })] }), _jsxs("div", { className: "mt-3", children: [_jsx("p", { className: "text-xs font-medium text-[var(--muted-foreground)] mb-2", children: "Social Preview" }), _jsxs("div", { className: "rounded-lg border border-[var(--border)] overflow-hidden bg-[var(--muted)]", children: [seoData.ogImage ? (_jsx("div", { className: "aspect-video bg-[var(--muted)] flex items-center justify-center overflow-hidden", children: _jsx("img", { src: seoData.ogImage, alt: "OG preview", className: "w-full h-full object-cover" }) })) : (_jsx("div", { className: "aspect-video bg-[var(--muted)] flex items-center justify-center text-[var(--muted-foreground)] text-sm", children: "No OG image set" })), _jsxs("div", { className: "p-3", children: [_jsx("div", { className: "text-sm font-medium text-[var(--foreground)] line-clamp-1", children: displayTitle }), _jsx("div", { className: "text-xs text-[var(--muted-foreground)] mt-1 line-clamp-2", children: displayDesc.slice(0, 100) }), _jsx("div", { className: "text-xs text-[var(--muted-foreground)] mt-1 truncate", children: siteUrl })] })] })] })] }) }), _jsx(Section, { id: "advanced", title: "Advanced", icon: _jsx(Settings2, { className: "h-4 w-4" }), expanded: expandedSections.includes('advanced'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-4", children: [_jsx(ToggleSwitch, { label: "Cornerstone Content", description: "Mark as cornerstone \u2014 your most important, comprehensive articles", checked: seoData.isCornerstone ?? false, onChange: (v) => update({ isCornerstone: v }) }), seoData.isCornerstone && (_jsxs("div", { className: "flex items-center gap-1.5 text-xs text-amber-600 bg-amber-50 rounded-md px-2.5 py-1.5", children: [_jsx(Star, { className: "h-3.5 w-3.5" }), "Cornerstone content is held to stricter SEO standards"] })), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-[var(--muted-foreground)] mb-1", children: "Schema Type" }), _jsx("select", { value: seoData.schemaType ?? 'Article', onChange: (e) => update({ schemaType: e.target.value }), className: "w-full px-3 py-1.5 text-sm border border-[var(--border)] rounded-lg bg-[var(--background)] text-[var(--foreground)] focus:outline-none focus:ring-2 focus:ring-[var(--primary)]", children: SCHEMA_TYPES.map((t) => (_jsx("option", { value: t, children: t }, t))) })] })] }) })] })] }));
374
+ }, children: [_jsxs(Select.Trigger, { "aria-labelledby": "robots-policy-label", className: "border-border bg-background text-foreground focus:ring-primary flex w-full items-center justify-between rounded-lg border px-3 py-1.5 text-sm focus:ring-2 focus:outline-none", children: [_jsx(Select.Value, {}), _jsx(Select.Icon, { children: _jsx(ChevronDown, { className: "text-muted-foreground h-4 w-4" }) })] }), _jsx(Select.Portal, { children: _jsx(Select.Content, { className: "border-border bg-card z-50 overflow-hidden rounded-lg border shadow-md", children: _jsx(Select.Viewport, { className: "p-1", children: ROBOTS_POLICY_OPTIONS.map((option) => (_jsxs(Select.Item, { value: option.value, className: "text-foreground hover:bg-muted focus:bg-muted relative flex cursor-pointer items-center rounded-md py-1.5 pr-3 pl-8 text-sm outline-none select-none", children: [_jsx(Select.ItemIndicator, { className: "absolute left-2 inline-flex items-center", children: _jsx(Check, { className: "h-4 w-4" }) }), _jsx(Select.ItemText, { children: option.label })] }, option.value))) }) }) })] }), _jsx("p", { className: "text-muted-foreground mt-1 text-xs", children: "Use inheritance for most pages. Override only when a page needs different index/follow behavior." })] }) }) }), _jsx(Section, { id: "preview", title: "Search Preview", icon: _jsx(Globe, { className: "h-4 w-4" }), expanded: expandedSections.includes('preview'), onToggle: toggleSection, children: _jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--background)] p-3", children: [_jsx("div", { className: "line-clamp-1 cursor-pointer text-sm text-blue-600 hover:underline", children: metaTitle || title || 'Page Title' }), _jsxs("div", { className: "mt-1 truncate text-xs text-green-700", children: [siteUrl, "/", slug] }), _jsx("div", { className: "mt-1 line-clamp-2 text-sm text-[var(--muted-foreground)]", children: metaDesc ||
375
+ 'Add a meta description to see how this page will appear in search results.' })] }) }), _jsx(Section, { id: "social", title: "Social Media", icon: _jsx(Share2, { className: "h-4 w-4" }), expanded: expandedSections.includes('social'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "OG Title", value: seoData.ogTitle ?? '', onChange: (v) => update({ ogTitle: v }), placeholder: metaTitle || title || 'Leave blank to use meta title' }), _jsx(TextareaField, { label: "OG Description", value: seoData.ogDescription ?? '', onChange: (v) => update({ ogDescription: v }), rows: 2, placeholder: metaDesc || 'Leave blank to use meta description' }), _jsx(InputField, { label: "OG Image URL", value: seoData.ogImage ?? '', onChange: (v) => update({ ogImage: v }), placeholder: "https://example.com/og-image.jpg", type: "url" }), _jsxs("div", { className: "mt-3 border-t border-[var(--border)] pt-3", children: [_jsx("p", { className: "mb-2 text-xs font-medium text-[var(--muted-foreground)]", children: "Twitter / X Overrides" }), _jsxs("div", { className: "space-y-3", children: [_jsx(InputField, { label: "Twitter Title", value: seoData.twitterTitle ?? '', onChange: (v) => update({ twitterTitle: v }), placeholder: "Leave blank to use OG title" }), _jsx(TextareaField, { label: "Twitter Description", value: seoData.twitterDescription ?? '', onChange: (v) => update({ twitterDescription: v }), rows: 2, placeholder: "Leave blank to use OG description" }), _jsx(InputField, { label: "Twitter Image URL", value: seoData.twitterImage ?? '', onChange: (v) => update({ twitterImage: v }), placeholder: "Leave blank to use OG image", type: "url" })] })] }), _jsxs("div", { className: "mt-3", children: [_jsx("p", { className: "mb-2 text-xs font-medium text-[var(--muted-foreground)]", children: "Social Preview" }), _jsxs("div", { className: "overflow-hidden rounded-lg border border-[var(--border)] bg-[var(--muted)]", children: [seoData.ogImage ? (_jsx("div", { className: "flex aspect-video items-center justify-center overflow-hidden bg-[var(--muted)]", children: _jsx("img", { src: seoData.ogImage, alt: "OG preview", className: "h-full w-full object-cover" }) })) : (_jsx("div", { className: "flex aspect-video items-center justify-center bg-[var(--muted)] text-sm text-[var(--muted-foreground)]", children: "No OG image set" })), _jsxs("div", { className: "p-3", children: [_jsx("div", { className: "line-clamp-1 text-sm font-medium text-[var(--foreground)]", children: displayTitle }), _jsx("div", { className: "mt-1 line-clamp-2 text-xs text-[var(--muted-foreground)]", children: displayDesc.slice(0, 100) }), _jsx("div", { className: "mt-1 truncate text-xs text-[var(--muted-foreground)]", children: siteUrl })] })] })] })] }) }), _jsx(Section, { id: "advanced", title: "Advanced", icon: _jsx(Settings2, { className: "h-4 w-4" }), expanded: expandedSections.includes('advanced'), onToggle: toggleSection, children: _jsxs("div", { className: "space-y-4", children: [_jsx(ToggleSwitch, { label: "Cornerstone Content", description: "Mark as cornerstone \u2014 your most important, comprehensive articles", checked: seoData.isCornerstone ?? false, onChange: (v) => update({ isCornerstone: v }) }), seoData.isCornerstone && (_jsxs("div", { className: "flex items-center gap-1.5 rounded-md bg-amber-50 px-2.5 py-1.5 text-xs text-amber-600", children: [_jsx(Star, { className: "h-3.5 w-3.5" }), "Cornerstone content is held to stricter SEO standards"] })), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-[var(--muted-foreground)]", children: "Schema Type" }), _jsx("select", { value: seoData.schemaType ?? 'Article', onChange: (e) => update({ schemaType: e.target.value }), className: "w-full rounded-lg border border-[var(--border)] bg-[var(--background)] px-3 py-1.5 text-sm text-[var(--foreground)] focus:ring-2 focus:ring-[var(--primary)] focus:outline-none", children: SCHEMA_TYPES.map((t) => (_jsx("option", { value: t, children: t }, t))) })] })] }) })] })] }));
376
376
  }
377
377
  //# sourceMappingURL=SEOPanel.js.map
@@ -6,7 +6,7 @@ import { useApiData } from '../lib/useApiData.js';
6
6
  function ScoreBadge({ score }) {
7
7
  const color = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-amber-500' : 'text-red-500';
8
8
  const bg = score >= 80 ? 'bg-green-50' : score >= 60 ? 'bg-amber-50' : 'bg-red-50';
9
- return (_jsx("span", { className: `inline-flex items-center justify-center w-9 h-9 rounded-full text-sm font-semibold ${color} ${bg}`, children: score }));
9
+ return (_jsx("span", { className: `inline-flex h-9 w-9 items-center justify-center rounded-full text-sm font-semibold ${color} ${bg}`, children: score }));
10
10
  }
11
11
  export function SEOPerformance({ onNavigate }) {
12
12
  const { data, loading, error } = useApiData('/seo/summary');
@@ -19,6 +19,6 @@ export function SEOPerformance({ onNavigate }) {
19
19
  const topContent = data.topContent ?? [];
20
20
  const totalPages = Math.max(1, Math.ceil(topContent.length / perPage));
21
21
  const visible = topContent.slice(page * perPage, (page + 1) * perPage);
22
- return (_jsxs("div", { className: "bg-white rounded-lg border border-gray-200", children: [_jsxs("div", { className: "p-4 border-b border-gray-200 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Search, { className: "w-4 h-4 text-gray-500" }), _jsx("h2", { className: "text-sm font-semibold text-gray-900", children: "SEO Performance" })] }), totalIssues > 0 && (_jsxs("span", { className: "text-xs text-gray-500", children: [totalIssues, " issue", totalIssues !== 1 ? 's' : '', " found"] }))] }), _jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-12 divide-y lg:divide-y-0 lg:divide-x divide-gray-200", children: [_jsxs("div", { className: "lg:col-span-7 p-4", children: [_jsx("h3", { className: "text-sm font-medium text-gray-700 mb-3", children: "Top Performing Content" }), _jsxs("div", { className: "space-y-2", children: [visible.map((item) => (_jsxs("div", { className: "flex items-center justify-between py-2", children: [_jsxs("div", { className: "flex-1 min-w-0 mr-3", children: [_jsx("p", { className: "text-sm font-medium text-gray-900 truncate", children: item.title }), _jsx("p", { className: "text-xs text-gray-500 capitalize", children: item.collection })] }), _jsx(ScoreBadge, { score: item.score })] }, item.id))), visible.length === 0 && (_jsx("p", { className: "text-sm text-gray-400 py-4 text-center", children: "No published content yet" }))] }), topContent.length > perPage && (_jsxs("div", { className: "flex items-center justify-between mt-3 pt-3 border-t border-gray-100 text-xs text-gray-500", children: [_jsxs("span", { children: ["Showing ", page * perPage + 1, "-", Math.min((page + 1) * perPage, topContent.length), " of", ' ', topContent.length] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => setPage(Math.max(0, page - 1)), disabled: page === 0, className: "p-1 rounded hover:bg-gray-100 disabled:opacity-30", children: _jsx(ChevronLeft, { className: "w-3.5 h-3.5" }) }), _jsxs("span", { children: ["Page ", page + 1, " of ", totalPages] }), _jsx("button", { onClick: () => setPage(Math.min(totalPages - 1, page + 1)), disabled: page >= totalPages - 1, className: "p-1 rounded hover:bg-gray-100 disabled:opacity-30", children: _jsx(ChevronRight, { className: "w-3.5 h-3.5" }) })] })] }))] }), _jsxs("div", { className: "lg:col-span-5 p-4", children: [_jsx("h3", { className: "text-sm font-medium text-gray-700 mb-3", children: "SEO Issues" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FileWarning, { className: "w-4 h-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Missing meta descriptions" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.missingMetaDescriptions })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(LinkIcon, { className: "w-4 h-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Broken internal links" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.brokenInternalLinks })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ImageOff, { className: "w-4 h-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Missing alt text" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.missingAltText })] })] }), totalIssues > 0 && (_jsx("button", { onClick: () => onNavigate?.('/seo'), className: "mt-4 text-sm text-blue-600 hover:text-blue-700 font-medium", children: "View All Issues" }))] })] })] }));
22
+ return (_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Search, { className: "h-4 w-4 text-gray-500" }), _jsx("h2", { className: "text-sm font-semibold text-gray-900", children: "SEO Performance" })] }), totalIssues > 0 && (_jsxs("span", { className: "text-xs text-gray-500", children: [totalIssues, " issue", totalIssues !== 1 ? 's' : '', " found"] }))] }), _jsxs("div", { className: "grid grid-cols-1 divide-y divide-gray-200 lg:grid-cols-12 lg:divide-x lg:divide-y-0", children: [_jsxs("div", { className: "p-4 lg:col-span-7", children: [_jsx("h3", { className: "mb-3 text-sm font-medium text-gray-700", children: "Top Performing Content" }), _jsxs("div", { className: "space-y-2", children: [visible.map((item) => (_jsxs("div", { className: "flex items-center justify-between py-2", children: [_jsxs("div", { className: "mr-3 min-w-0 flex-1", children: [_jsx("p", { className: "truncate text-sm font-medium text-gray-900", children: item.title }), _jsx("p", { className: "text-xs text-gray-500 capitalize", children: item.collection })] }), _jsx(ScoreBadge, { score: item.score })] }, item.id))), visible.length === 0 && (_jsx("p", { className: "py-4 text-center text-sm text-gray-400", children: "No published content yet" }))] }), topContent.length > perPage && (_jsxs("div", { className: "mt-3 flex items-center justify-between border-t border-gray-100 pt-3 text-xs text-gray-500", children: [_jsxs("span", { children: ["Showing ", page * perPage + 1, "-", Math.min((page + 1) * perPage, topContent.length), " of", ' ', topContent.length] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => setPage(Math.max(0, page - 1)), disabled: page === 0, className: "rounded p-1 hover:bg-gray-100 disabled:opacity-30", children: _jsx(ChevronLeft, { className: "h-3.5 w-3.5" }) }), _jsxs("span", { children: ["Page ", page + 1, " of ", totalPages] }), _jsx("button", { onClick: () => setPage(Math.min(totalPages - 1, page + 1)), disabled: page >= totalPages - 1, className: "rounded p-1 hover:bg-gray-100 disabled:opacity-30", children: _jsx(ChevronRight, { className: "h-3.5 w-3.5" }) })] })] }))] }), _jsxs("div", { className: "p-4 lg:col-span-5", children: [_jsx("h3", { className: "mb-3 text-sm font-medium text-gray-700", children: "SEO Issues" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(FileWarning, { className: "h-4 w-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Missing meta descriptions" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.missingMetaDescriptions })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(LinkIcon, { className: "h-4 w-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Broken internal links" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.brokenInternalLinks })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(ImageOff, { className: "h-4 w-4 text-red-400" }), _jsx("span", { className: "text-sm text-gray-700", children: "Missing alt text" })] }), _jsx("span", { className: "text-sm font-semibold text-gray-900", children: issues.missingAltText })] })] }), totalIssues > 0 && (_jsx("button", { onClick: () => onNavigate?.('/seo'), className: "mt-4 text-sm font-medium text-blue-600 hover:text-blue-700", children: "View All Issues" }))] })] })] }));
23
23
  }
24
24
  //# sourceMappingURL=SEOPerformance.js.map
@@ -101,6 +101,6 @@ export function SchedulePublishDialog({ collectionSlug, documentId, scheduledAt,
101
101
  }
102
102
  if (!open)
103
103
  return null;
104
- return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [_jsx("div", { className: "fixed inset-0 bg-black/40", onClick: onClose }), _jsxs("div", { className: "relative w-full max-w-md rounded-lg bg-white shadow-xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "h-5 w-5 text-gray-600" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Schedule publishing" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-1.5 transition-colors hover:bg-gray-100", children: _jsx(X, { className: "h-5 w-5 text-gray-500" }) })] }), _jsxs("div", { className: "space-y-4 px-4 py-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Publish at" }), _jsxs("div", { className: "relative", children: [_jsx(Clock, { className: "pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-gray-400" }), _jsx("input", { type: "datetime-local", value: publishAt, onChange: (e) => setPublishAt(e.target.value), min: toLocalDateTimeInput(new Date(Date.now() + 60 * 1000)), className: "w-full rounded-md border border-gray-300 bg-white py-2 pl-9 pr-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" })] }), _jsx("p", { className: "text-xs text-gray-500", children: "The document will move from DRAFT to PUBLISHED at this time (your local timezone)." })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: includeUnpublish, onChange: (e) => setIncludeUnpublish(e.target.checked), className: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" }), "Also schedule an unpublish"] }), includeUnpublish && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Unpublish at" }), _jsxs("div", { className: "relative", children: [_jsx(Clock, { className: "pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-gray-400" }), _jsx("input", { type: "datetime-local", value: unpublishAt, onChange: (e) => setUnpublishAt(e.target.value), min: publishAt || toLocalDateTimeInput(new Date(Date.now() + 60 * 1000)), className: "w-full rounded-md border border-gray-300 bg-white py-2 pl-9 pr-3 text-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500" })] })] }))] }), _jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-gray-200 px-4 py-3", children: [hasExistingSchedule ? (_jsxs("button", { onClick: handleCancelSchedule, disabled: cancelling || saving, className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium text-red-700 hover:bg-red-50 disabled:opacity-50", children: [cancelling ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(X, { className: "h-4 w-4" })), "Cancel schedule"] })) : (_jsx("span", {})), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: onClose, className: "rounded-md px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", children: "Close" }), _jsxs("button", { onClick: handleSave, disabled: saving || cancelling, className: "inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50", children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Calendar, { className: "h-4 w-4" })), hasExistingSchedule ? 'Reschedule' : 'Schedule'] })] })] })] })] }));
104
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center p-4", children: [_jsx("div", { className: "fixed inset-0 bg-black/40", onClick: onClose }), _jsxs("div", { className: "relative w-full max-w-md rounded-lg bg-white shadow-xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { className: "h-5 w-5 text-gray-600" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Schedule publishing" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-1.5 transition-colors hover:bg-gray-100", children: _jsx(X, { className: "h-5 w-5 text-gray-500" }) })] }), _jsxs("div", { className: "space-y-4 px-4 py-4", children: [_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Publish at" }), _jsxs("div", { className: "relative", children: [_jsx(Clock, { className: "pointer-events-none absolute top-2.5 left-2.5 h-4 w-4 text-gray-400" }), _jsx("input", { type: "datetime-local", value: publishAt, onChange: (e) => setPublishAt(e.target.value), min: toLocalDateTimeInput(new Date(Date.now() + 60 * 1000)), className: "w-full rounded-md border border-gray-300 bg-white py-2 pr-3 pl-9 text-sm focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" })] }), _jsx("p", { className: "text-xs text-gray-500", children: "The document will move from DRAFT to PUBLISHED at this time (your local timezone)." })] }), _jsxs("label", { className: "flex items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: includeUnpublish, onChange: (e) => setIncludeUnpublish(e.target.checked), className: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" }), "Also schedule an unpublish"] }), includeUnpublish && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Unpublish at" }), _jsxs("div", { className: "relative", children: [_jsx(Clock, { className: "pointer-events-none absolute top-2.5 left-2.5 h-4 w-4 text-gray-400" }), _jsx("input", { type: "datetime-local", value: unpublishAt, onChange: (e) => setUnpublishAt(e.target.value), min: publishAt || toLocalDateTimeInput(new Date(Date.now() + 60 * 1000)), className: "w-full rounded-md border border-gray-300 bg-white py-2 pr-3 pl-9 text-sm focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" })] })] }))] }), _jsxs("div", { className: "flex items-center justify-between gap-2 border-t border-gray-200 px-4 py-3", children: [hasExistingSchedule ? (_jsxs("button", { onClick: handleCancelSchedule, disabled: cancelling || saving, className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm font-medium text-red-700 hover:bg-red-50 disabled:opacity-50", children: [cancelling ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(X, { className: "h-4 w-4" })), "Cancel schedule"] })) : (_jsx("span", {})), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: onClose, className: "rounded-md px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", children: "Close" }), _jsxs("button", { onClick: handleSave, disabled: saving || cancelling, className: "inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50", children: [saving ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Calendar, { className: "h-4 w-4" })), hasExistingSchedule ? 'Reschedule' : 'Schedule'] })] })] })] })] }));
105
105
  }
106
106
  //# sourceMappingURL=SchedulePublishDialog.js.map
@@ -78,6 +78,6 @@ export function SharePreviewLinkDialog({ collectionSlug, documentId, documentSlu
78
78
  return (_jsxs("button", { onClick: () => setTtl(choice.seconds), className: `rounded-md border px-3 py-2 text-left text-sm transition-colors ${selected
79
79
  ? 'border-blue-500 bg-blue-50 text-blue-900'
80
80
  : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50'}`, children: [_jsx("div", { className: "font-medium", children: choice.label }), _jsx("div", { className: "text-xs text-gray-500", children: choice.hint })] }, choice.seconds));
81
- }) }), _jsx("p", { className: "text-xs text-gray-500", children: "Preview tokens can't be revoked individually \u2014 pick the shortest TTL that fits." })] }), previewUrl ? (_jsxs("div", { className: "space-y-2 rounded-lg border border-gray-200 bg-gray-50 p-3", children: [_jsx("label", { className: "text-xs font-medium uppercase tracking-wide text-gray-500", children: "Preview URL" }), _jsxs("div", { className: "flex items-stretch gap-2", children: [_jsx("input", { readOnly: true, value: previewUrl, onFocus: (e) => e.currentTarget.select(), className: "flex-1 rounded-md border border-gray-300 bg-white px-2 py-1.5 font-mono text-xs" }), _jsxs("button", { onClick: copyToClipboard, className: "inline-flex items-center gap-1.5 rounded-md bg-gray-900 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-700", children: [copied ? _jsx(Check, { className: "h-3.5 w-3.5" }) : _jsx(Copy, { className: "h-3.5 w-3.5" }), copied ? 'Copied' : 'Copy'] })] }), expiresAt && (_jsxs("p", { className: "text-xs text-gray-500", children: ["Expires ", new Date(expiresAt).toLocaleString()] }))] })) : null] }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-gray-200 px-4 py-3", children: [_jsx("button", { onClick: onClose, className: "rounded-md px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", children: "Close" }), _jsxs("button", { onClick: generate, disabled: generating, className: "inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50", children: [generating ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Link2, { className: "h-4 w-4" })), previewUrl ? 'Generate new link' : 'Generate link'] })] })] })] }));
81
+ }) }), _jsx("p", { className: "text-xs text-gray-500", children: "Preview tokens can't be revoked individually \u2014 pick the shortest TTL that fits." })] }), previewUrl ? (_jsxs("div", { className: "space-y-2 rounded-lg border border-gray-200 bg-gray-50 p-3", children: [_jsx("label", { className: "text-xs font-medium tracking-wide text-gray-500 uppercase", children: "Preview URL" }), _jsxs("div", { className: "flex items-stretch gap-2", children: [_jsx("input", { readOnly: true, value: previewUrl, onFocus: (e) => e.currentTarget.select(), className: "flex-1 rounded-md border border-gray-300 bg-white px-2 py-1.5 font-mono text-xs" }), _jsxs("button", { onClick: copyToClipboard, className: "inline-flex items-center gap-1.5 rounded-md bg-gray-900 px-3 py-1.5 text-xs font-medium text-white hover:bg-gray-700", children: [copied ? _jsx(Check, { className: "h-3.5 w-3.5" }) : _jsx(Copy, { className: "h-3.5 w-3.5" }), copied ? 'Copied' : 'Copy'] })] }), expiresAt && (_jsxs("p", { className: "text-xs text-gray-500", children: ["Expires ", new Date(expiresAt).toLocaleString()] }))] })) : null] }), _jsxs("div", { className: "flex items-center justify-end gap-2 border-t border-gray-200 px-4 py-3", children: [_jsx("button", { onClick: onClose, className: "rounded-md px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100", children: "Close" }), _jsxs("button", { onClick: generate, disabled: generating, className: "inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white hover:bg-blue-700 disabled:opacity-50", children: [generating ? (_jsx(Loader2, { className: "h-4 w-4 animate-spin" })) : (_jsx(Link2, { className: "h-4 w-4" })), previewUrl ? 'Generate new link' : 'Generate link'] })] })] })] }));
82
82
  }
83
83
  //# sourceMappingURL=SharePreviewLinkDialog.js.map
@@ -98,12 +98,12 @@ const editorStyles = `
98
98
  }
99
99
  `;
100
100
  function ToolbarButton({ onClick, isActive = false, disabled = false, title, children, }) {
101
- return (_jsx("button", { type: "button", onClick: onClick, disabled: disabled, title: title, className: `p-1.5 rounded transition-colors ${isActive
101
+ return (_jsx("button", { type: "button", onClick: onClick, disabled: disabled, title: title, className: `rounded p-1.5 transition-colors ${isActive
102
102
  ? 'bg-blue-100 text-blue-700'
103
- : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'} ${disabled ? 'opacity-40 cursor-not-allowed' : ''}`, children: children }));
103
+ : 'text-gray-600 hover:bg-gray-100 hover:text-gray-900'} ${disabled ? 'cursor-not-allowed opacity-40' : ''}`, children: children }));
104
104
  }
105
105
  function Divider() {
106
- return _jsx("div", { className: "w-px h-6 bg-gray-200 mx-1" });
106
+ return _jsx("div", { className: "mx-1 h-6 w-px bg-gray-200" });
107
107
  }
108
108
  function Toolbar({ editor, onOpenMediaPicker }) {
109
109
  const addLink = () => {
@@ -121,7 +121,7 @@ function Toolbar({ editor, onOpenMediaPicker }) {
121
121
  editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run();
122
122
  };
123
123
  const isInTable = editor.isActive('table');
124
- return (_jsxs("div", { className: "border-b border-gray-200 bg-gray-50 p-2 flex items-center gap-0.5 flex-wrap sticky top-0 z-10", children: [_jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), isActive: editor.isActive('bold'), title: "Bold (Ctrl+B)", children: _jsx(Bold, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), isActive: editor.isActive('italic'), title: "Italic (Ctrl+I)", children: _jsx(Italic, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleUnderline().run(), isActive: editor.isActive('underline'), title: "Underline (Ctrl+U)", children: _jsx(Underline, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), isActive: editor.isActive('strike'), title: "Strikethrough", children: _jsx(Strikethrough, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), isActive: editor.isActive('code'), title: "Inline code", children: _jsx(Code, { className: "w-4 h-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(), isActive: editor.isActive('heading', { level: 1 }), title: "Heading 1", children: _jsx(Heading1, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(), isActive: editor.isActive('heading', { level: 2 }), title: "Heading 2", children: _jsx(Heading2, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(), isActive: editor.isActive('heading', { level: 3 }), title: "Heading 3", children: _jsx(Heading3, { className: "w-4 h-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBulletList().run(), isActive: editor.isActive('bulletList'), title: "Bullet list", children: _jsx(List, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleOrderedList().run(), isActive: editor.isActive('orderedList'), title: "Ordered list", children: _jsx(ListOrdered, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBlockquote().run(), isActive: editor.isActive('blockquote'), title: "Blockquote", children: _jsx(Quote, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleCodeBlock().run(), isActive: editor.isActive('codeBlock'), title: "Code block", children: _jsx(FileCode, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setHorizontalRule().run(), title: "Horizontal rule", children: _jsx(Minus, { className: "w-4 h-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('left').run(), isActive: editor.isActive({ textAlign: 'left' }), title: "Align left", children: _jsx(AlignLeft, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('center').run(), isActive: editor.isActive({ textAlign: 'center' }), title: "Align center", children: _jsx(AlignCenter, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('right').run(), isActive: editor.isActive({ textAlign: 'right' }), title: "Align right", children: _jsx(AlignRight, { className: "w-4 h-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: addLink, isActive: editor.isActive('link'), title: "Insert link", children: _jsx(LinkIcon, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: onOpenMediaPicker, title: "Insert image", children: _jsx(ImageIcon, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: insertTable, title: "Insert table (3\u00D73)", children: _jsx(TableIcon, { className: "w-4 h-4" }) }), isInTable && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addColumnBefore().run(), title: "Add column before", children: _jsx(Columns, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addColumnAfter().run(), title: "Add column after", children: _jsx(Columns, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteColumn().run(), title: "Delete column", children: _jsx(Columns, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addRowBefore().run(), title: "Add row before", children: _jsx(Rows, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addRowAfter().run(), title: "Add row after", children: _jsx(Rows, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteRow().run(), title: "Delete row", children: _jsx(Rows, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteTable().run(), title: "Delete table", children: _jsx(Trash2, { className: "w-4 h-4" }) })] })), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: "Undo", children: _jsx(Undo, { className: "w-4 h-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: "Redo", children: _jsx(Redo, { className: "w-4 h-4" }) })] }));
124
+ return (_jsxs("div", { className: "sticky top-0 z-10 flex flex-wrap items-center gap-0.5 border-b border-gray-200 bg-gray-50 p-2", children: [_jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBold().run(), isActive: editor.isActive('bold'), title: "Bold (Ctrl+B)", children: _jsx(Bold, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleItalic().run(), isActive: editor.isActive('italic'), title: "Italic (Ctrl+I)", children: _jsx(Italic, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleUnderline().run(), isActive: editor.isActive('underline'), title: "Underline (Ctrl+U)", children: _jsx(Underline, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleStrike().run(), isActive: editor.isActive('strike'), title: "Strikethrough", children: _jsx(Strikethrough, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleCode().run(), isActive: editor.isActive('code'), title: "Inline code", children: _jsx(Code, { className: "h-4 w-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 1 }).run(), isActive: editor.isActive('heading', { level: 1 }), title: "Heading 1", children: _jsx(Heading1, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 2 }).run(), isActive: editor.isActive('heading', { level: 2 }), title: "Heading 2", children: _jsx(Heading2, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleHeading({ level: 3 }).run(), isActive: editor.isActive('heading', { level: 3 }), title: "Heading 3", children: _jsx(Heading3, { className: "h-4 w-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBulletList().run(), isActive: editor.isActive('bulletList'), title: "Bullet list", children: _jsx(List, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleOrderedList().run(), isActive: editor.isActive('orderedList'), title: "Ordered list", children: _jsx(ListOrdered, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleBlockquote().run(), isActive: editor.isActive('blockquote'), title: "Blockquote", children: _jsx(Quote, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().toggleCodeBlock().run(), isActive: editor.isActive('codeBlock'), title: "Code block", children: _jsx(FileCode, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setHorizontalRule().run(), title: "Horizontal rule", children: _jsx(Minus, { className: "h-4 w-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('left').run(), isActive: editor.isActive({ textAlign: 'left' }), title: "Align left", children: _jsx(AlignLeft, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('center').run(), isActive: editor.isActive({ textAlign: 'center' }), title: "Align center", children: _jsx(AlignCenter, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().setTextAlign('right').run(), isActive: editor.isActive({ textAlign: 'right' }), title: "Align right", children: _jsx(AlignRight, { className: "h-4 w-4" }) }), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: addLink, isActive: editor.isActive('link'), title: "Insert link", children: _jsx(LinkIcon, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: onOpenMediaPicker, title: "Insert image", children: _jsx(ImageIcon, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: insertTable, title: "Insert table (3\u00D73)", children: _jsx(TableIcon, { className: "h-4 w-4" }) }), isInTable && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addColumnBefore().run(), title: "Add column before", children: _jsx(Columns, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addColumnAfter().run(), title: "Add column after", children: _jsx(Columns, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteColumn().run(), title: "Delete column", children: _jsx(Columns, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addRowBefore().run(), title: "Add row before", children: _jsx(Rows, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().addRowAfter().run(), title: "Add row after", children: _jsx(Rows, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteRow().run(), title: "Delete row", children: _jsx(Rows, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().deleteTable().run(), title: "Delete table", children: _jsx(Trash2, { className: "h-4 w-4" }) })] })), _jsx(Divider, {}), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().undo().run(), disabled: !editor.can().undo(), title: "Undo", children: _jsx(Undo, { className: "h-4 w-4" }) }), _jsx(ToolbarButton, { onClick: () => editor.chain().focus().redo().run(), disabled: !editor.can().redo(), title: "Redo", children: _jsx(Redo, { className: "h-4 w-4" }) })] }));
125
125
  }
126
126
  export function TipTapEditor({ content, onChange, placeholder, editable = true, className, }) {
127
127
  const [mediaPickerOpen, setMediaPickerOpen] = useState(false);
@@ -166,6 +166,6 @@ export function TipTapEditor({ content, onChange, placeholder, editable = true,
166
166
  .setImage({ src: url, alt: alt ?? '' })
167
167
  .run();
168
168
  };
169
- return (_jsxs("div", { className: `border border-gray-200 rounded-lg overflow-hidden bg-white ${className ?? ''}`, children: [editable && _jsx(Toolbar, { editor: editor, onOpenMediaPicker: () => setMediaPickerOpen(true) }), _jsx(EditorContent, { editor: editor }), _jsx("style", { dangerouslySetInnerHTML: { __html: editorStyles } }), _jsx(MediaPickerModal, { open: mediaPickerOpen, onClose: () => setMediaPickerOpen(false), onSelect: handleImageSelected, accept: "image/*" })] }));
169
+ return (_jsxs("div", { className: `overflow-hidden rounded-lg border border-gray-200 bg-white ${className ?? ''}`, children: [editable && _jsx(Toolbar, { editor: editor, onOpenMediaPicker: () => setMediaPickerOpen(true) }), _jsx(EditorContent, { editor: editor }), _jsx("style", { dangerouslySetInnerHTML: { __html: editorStyles } }), _jsx(MediaPickerModal, { open: mediaPickerOpen, onClose: () => setMediaPickerOpen(false), onSelect: handleImageSelected, accept: "image/*" })] }));
170
170
  }
171
171
  //# sourceMappingURL=TipTapEditor.js.map
@@ -58,13 +58,13 @@ export function VersionHistory({ collectionSlug, documentId, open, onClose, onRe
58
58
  }
59
59
  if (!open)
60
60
  return null;
61
- return (_jsxs("div", { className: "fixed inset-0 z-50 flex justify-end", children: [_jsx("div", { className: "fixed inset-0 bg-black/30", onClick: onClose }), _jsxs("div", { className: "relative w-full max-w-md bg-white shadow-xl flex flex-col animate-in slide-in-from-right", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Clock, { className: "w-5 h-5 text-gray-600" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Version History" })] }), _jsx("button", { onClick: onClose, className: "p-1.5 hover:bg-gray-100 rounded-lg transition-colors", children: _jsx(X, { className: "w-5 h-5 text-gray-500" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: loading ? (_jsx("div", { className: "flex items-center justify-center py-16", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-gray-400" }) })) : versions.length === 0 ? (_jsx("div", { className: "text-center py-16 text-sm text-gray-500", children: "No version history available" })) : (_jsx("div", { className: "divide-y divide-gray-100", children: versions.map((version, index) => {
61
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex justify-end", children: [_jsx("div", { className: "fixed inset-0 bg-black/30", onClick: onClose }), _jsxs("div", { className: "animate-in slide-in-from-right relative flex w-full max-w-md flex-col bg-white shadow-xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Clock, { className: "h-5 w-5 text-gray-600" }), _jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Version History" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-1.5 transition-colors hover:bg-gray-100", children: _jsx(X, { className: "h-5 w-5 text-gray-500" }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto", children: loading ? (_jsx("div", { className: "flex items-center justify-center py-16", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-gray-400" }) })) : versions.length === 0 ? (_jsx("div", { className: "py-16 text-center text-sm text-gray-500", children: "No version history available" })) : (_jsx("div", { className: "divide-y divide-gray-100", children: versions.map((version, index) => {
62
62
  const typeInfo = CHANGE_TYPE_LABELS[version.changeType] ?? {
63
63
  label: version.changeType,
64
64
  color: 'bg-gray-100 text-gray-800',
65
65
  };
66
66
  const isLatest = index === 0;
67
- return (_jsx("div", { className: "px-4 py-3 hover:bg-gray-50 transition-colors", children: _jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("span", { className: `inline-flex px-2 py-0.5 rounded-full text-xs font-medium ${typeInfo.color}`, children: typeInfo.label }), isLatest && (_jsx("span", { className: "text-xs text-gray-400 font-medium", children: "Current" }))] }), _jsxs("div", { className: "flex items-center gap-3 text-xs text-gray-500", children: [version.changedBy && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(User, { className: "w-3 h-3" }), version.changedBy.name ?? version.changedBy.email ?? 'Unknown'] })), _jsx("span", { title: new Date(version.createdAt).toLocaleString(), children: timeAgo(version.createdAt) })] })] }), !isLatest && (_jsxs("button", { onClick: () => handleRestore(version), disabled: restoring === version.id, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-blue-700 bg-blue-50 rounded-lg hover:bg-blue-100 transition-colors disabled:opacity-50", children: [restoring === version.id ? (_jsx(Loader2, { className: "w-3.5 h-3.5 animate-spin" })) : (_jsx(RotateCcw, { className: "w-3.5 h-3.5" })), "Restore"] }))] }) }, version.id));
67
+ return (_jsx("div", { className: "px-4 py-3 transition-colors hover:bg-gray-50", children: _jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("span", { className: `inline-flex rounded-full px-2 py-0.5 text-xs font-medium ${typeInfo.color}`, children: typeInfo.label }), isLatest && (_jsx("span", { className: "text-xs font-medium text-gray-400", children: "Current" }))] }), _jsxs("div", { className: "flex items-center gap-3 text-xs text-gray-500", children: [version.changedBy && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(User, { className: "h-3 w-3" }), version.changedBy.name ?? version.changedBy.email ?? 'Unknown'] })), _jsx("span", { title: new Date(version.createdAt).toLocaleString(), children: timeAgo(version.createdAt) })] })] }), !isLatest && (_jsxs("button", { onClick: () => handleRestore(version), disabled: restoring === version.id, className: "flex items-center gap-1.5 rounded-lg bg-blue-50 px-2.5 py-1.5 text-xs font-medium text-blue-700 transition-colors hover:bg-blue-100 disabled:opacity-50", children: [restoring === version.id ? (_jsx(Loader2, { className: "h-3.5 w-3.5 animate-spin" })) : (_jsx(RotateCcw, { className: "h-3.5 w-3.5" })), "Restore"] }))] }) }, version.id));
68
68
  }) })) })] })] }));
69
69
  }
70
70
  //# sourceMappingURL=VersionHistory.js.map
@@ -1,5 +1,35 @@
1
- export interface BadgeProps {
2
- status: 'published' | 'draft' | 'archived' | 'scheduled';
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import { type VariantProps } from '../../lib/cv.js';
3
+ declare const badge: (props?: ({
4
+ tone?: "primary" | "danger" | "neutral" | "success" | "warning" | "info" | undefined;
5
+ size?: "sm" | "md" | "lg" | undefined;
6
+ } & {
7
+ class?: string | false | null | undefined;
8
+ className?: string | false | null | undefined;
9
+ }) | undefined) => string;
10
+ export type BadgeVariants = VariantProps<typeof badge>;
11
+ /**
12
+ * Map document statuses to badge tones. Exposed so callers can reuse the
13
+ * mapping (e.g. for the same status rendered as a dot indicator).
14
+ */
15
+ export declare const STATUS_TONE: Record<DocumentStatus, BadgeVariants['tone']>;
16
+ export declare const STATUS_LABEL: Record<DocumentStatus, string>;
17
+ export type DocumentStatus = 'published' | 'draft' | 'archived' | 'scheduled';
18
+ export interface BadgeProps extends HTMLAttributes<HTMLSpanElement>, BadgeVariants {
19
+ /**
20
+ * Shorthand for the canonical document status badge. When set, takes
21
+ * precedence over `tone` and uses the matching label.
22
+ */
23
+ status?: DocumentStatus;
24
+ /** Render as outlined (border + transparent background). */
25
+ outline?: boolean;
26
+ children?: ReactNode;
3
27
  }
4
- export declare function Badge({ status }: BadgeProps): import("react/jsx-runtime").JSX.Element;
28
+ /**
29
+ * Generic typed badge. Pass `status` for the canonical document-status
30
+ * variants (preserves the original Badge API), or `tone` / `outline` /
31
+ * `size` for everything else.
32
+ */
33
+ export declare function Badge({ status, tone, outline, size, className, children, ...rest }: BadgeProps): import("react/jsx-runtime").JSX.Element;
34
+ export { badge as badgeVariants };
5
35
  //# sourceMappingURL=Badge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAA;CACzD;AAgBD,wBAAgB,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,UAAU,2CAQ3C"}
1
+ {"version":3,"file":"Badge.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACtD,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEvD,QAAA,MAAM,KAAK;;;;;;yBAiBT,CAAA;AAEF,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,KAAK,CAAC,CAAA;AAEtD;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAKrE,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAKvD,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAA;AAE7E,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,eAAe,CAAC,EAAE,aAAa;IAChF;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAID;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,UAAU,2CAc9F;AAED,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,CAAA"}
@@ -1,17 +1,51 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- const statusClasses = {
3
- published: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400',
4
- draft: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300',
5
- archived: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',
6
- scheduled: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
2
+ import { cv } from '../../lib/cv.js';
3
+ const badge = cv('inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium', {
4
+ variants: {
5
+ tone: {
6
+ neutral: 'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300',
7
+ success: 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/30 dark:text-emerald-400',
8
+ warning: 'bg-amber-100 text-amber-800 dark:bg-amber-900/30 dark:text-amber-400',
9
+ danger: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
10
+ info: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
11
+ primary: 'bg-[var(--primary)]/15 text-[var(--primary)] dark:bg-[var(--primary)]/25',
12
+ },
13
+ size: {
14
+ sm: 'px-2 py-0.5 text-[10px]',
15
+ md: 'px-2.5 py-0.5 text-xs',
16
+ lg: 'px-3 py-1 text-sm',
17
+ },
18
+ },
19
+ defaultVariants: { tone: 'neutral', size: 'md' },
20
+ });
21
+ /**
22
+ * Map document statuses to badge tones. Exposed so callers can reuse the
23
+ * mapping (e.g. for the same status rendered as a dot indicator).
24
+ */
25
+ export const STATUS_TONE = {
26
+ published: 'success',
27
+ draft: 'neutral',
28
+ archived: 'warning',
29
+ scheduled: 'info',
7
30
  };
8
- const statusLabels = {
31
+ export const STATUS_LABEL = {
9
32
  published: 'Published',
10
33
  draft: 'Draft',
11
34
  archived: 'Archived',
12
35
  scheduled: 'Scheduled',
13
36
  };
14
- export function Badge({ status }) {
15
- return (_jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${statusClasses[status]}`, children: statusLabels[status] }));
37
+ const OUTLINE_CLASS = 'border border-current bg-transparent';
38
+ /**
39
+ * Generic typed badge. Pass `status` for the canonical document-status
40
+ * variants (preserves the original Badge API), or `tone` / `outline` /
41
+ * `size` for everything else.
42
+ */
43
+ export function Badge({ status, tone, outline, size, className, children, ...rest }) {
44
+ const extras = [outline ? OUTLINE_CLASS : '', className].filter(Boolean).join(' ');
45
+ if (status) {
46
+ return (_jsx("span", { className: badge({ tone: STATUS_TONE[status], size, class: extras }), ...rest, children: children ?? STATUS_LABEL[status] }));
47
+ }
48
+ return (_jsx("span", { className: badge({ tone, size, class: extras }), ...rest, children: children }));
16
49
  }
50
+ export { badge as badgeVariants };
17
51
  //# sourceMappingURL=Badge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":";AAIA,MAAM,aAAa,GAAyC;IAC1D,SAAS,EAAE,8EAA8E;IACzF,KAAK,EAAE,+DAA+D;IACtE,QAAQ,EAAE,sEAAsE;IAChF,SAAS,EAAE,kEAAkE;CAC9E,CAAA;AAED,MAAM,YAAY,GAAyC;IACzD,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,MAAM,UAAU,KAAK,CAAC,EAAE,MAAM,EAAc;IAC1C,OAAO,CACL,eACE,SAAS,EAAE,2EAA2E,aAAa,CAAC,MAAM,CAAC,EAAE,YAE5G,YAAY,CAAC,MAAM,CAAC,GAChB,CACR,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Badge.js","sourceRoot":"","sources":["../../../src/components/ui/Badge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAqB,MAAM,iBAAiB,CAAA;AAEvD,MAAM,KAAK,GAAG,EAAE,CAAC,yEAAyE,EAAE;IAC1F,QAAQ,EAAE;QACR,IAAI,EAAE;YACJ,OAAO,EAAE,+DAA+D;YACxE,OAAO,EAAE,8EAA8E;YACvF,OAAO,EAAE,sEAAsE;YAC/E,MAAM,EAAE,8DAA8D;YACtE,IAAI,EAAE,kEAAkE;YACxE,OAAO,EAAE,0EAA0E;SACpF;QACD,IAAI,EAAE;YACJ,EAAE,EAAE,yBAAyB;YAC7B,EAAE,EAAE,uBAAuB;YAC3B,EAAE,EAAE,mBAAmB;SACxB;KACF;IACD,eAAe,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE;CACjD,CAAC,CAAA;AAIF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAkD;IACxE,SAAS,EAAE,SAAS;IACpB,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,MAAM;CAClB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAmC;IAC1D,SAAS,EAAE,WAAW;IACtB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,UAAU;IACpB,SAAS,EAAE,WAAW;CACvB,CAAA;AAeD,MAAM,aAAa,GAAG,sCAAsC,CAAA;AAE5D;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAc;IAC7F,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAClF,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CACL,eAAM,SAAS,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAM,IAAI,YACjF,QAAQ,IAAI,YAAY,CAAC,MAAM,CAAC,GAC5B,CACR,CAAA;IACH,CAAC;IACD,OAAO,CACL,eAAM,SAAS,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAM,IAAI,YAC5D,QAAQ,GACJ,CACR,CAAA;AACH,CAAC;AAED,OAAO,EAAE,KAAK,IAAI,aAAa,EAAE,CAAA"}
@@ -1,12 +1,23 @@
1
1
  import { type ButtonHTMLAttributes, type ReactNode } from 'react';
2
- type ButtonVariant = 'primary' | 'secondary' | 'danger' | 'ghost';
3
- type ButtonSize = 'sm' | 'md' | 'lg';
4
- export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
5
- variant?: ButtonVariant;
6
- size?: ButtonSize;
2
+ import { type VariantProps } from '../../lib/cv.js';
3
+ declare const button: (props?: ({
4
+ variant?: "link" | "primary" | "secondary" | "danger" | "ghost" | "outline" | undefined;
5
+ size?: "icon" | "xs" | "sm" | "md" | "lg" | undefined;
6
+ } & {
7
+ class?: string | false | null | undefined;
8
+ className?: string | false | null | undefined;
9
+ }) | undefined) => string;
10
+ export type ButtonVariants = VariantProps<typeof button>;
11
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, ButtonVariants {
7
12
  loading?: boolean;
8
- children: ReactNode;
13
+ /** Stretch the button to fill its container width. */
14
+ full?: boolean;
15
+ /** Icon rendered before the children. Use with `size="icon"` for icon-only buttons. */
16
+ leftIcon?: ReactNode;
17
+ /** Icon rendered after the children. */
18
+ rightIcon?: ReactNode;
19
+ children?: ReactNode;
9
20
  }
10
- export declare function Button({ variant, size, loading, disabled, children, className, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
11
- export {};
21
+ export declare const Button: import("react").ForwardRefExoticComponent<ButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
22
+ export { button as buttonVariants };
12
23
  //# sourceMappingURL=Button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAEjE,KAAK,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAA;AACjE,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEpC,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC;IAC1E,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,SAAS,CAAA;CACpB;AAeD,wBAAgB,MAAM,CAAC,EACrB,OAAmB,EACnB,IAAW,EACX,OAAe,EACf,QAAQ,EACR,QAAQ,EACR,SAAc,EACd,GAAG,IAAI,EACR,EAAE,WAAW,2CA2Bb"}
1
+ {"version":3,"file":"Button.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Button.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,oBAAoB,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC7E,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEvD,QAAA,MAAM,MAAM;;;;;;yBA2BX,CAAA;AAED,MAAM,MAAM,cAAc,GAAG,YAAY,CAAC,OAAO,MAAM,CAAC,CAAA;AAExD,MAAM,WAAW,WAAY,SAAQ,oBAAoB,CAAC,iBAAiB,CAAC,EAAE,cAAc;IAC1F,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sDAAsD;IACtD,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uFAAuF;IACvF,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,wCAAwC;IACxC,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,eAAO,MAAM,MAAM,2GAkDjB,CAAA;AAEF,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,CAAA"}
@@ -1,17 +1,38 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- const variantClasses = {
4
- primary: 'bg-[var(--primary)] text-[var(--primary-foreground)] hover:opacity-90',
5
- secondary: 'bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:opacity-80',
6
- danger: 'bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90',
7
- ghost: 'bg-transparent hover:bg-[var(--accent)] text-[var(--foreground)]',
8
- };
9
- const sizeClasses = {
10
- sm: 'px-2.5 py-1 text-xs',
11
- md: 'px-4 py-2 text-sm',
12
- lg: 'px-6 py-2.5 text-base',
13
- };
14
- export function Button({ variant = 'primary', size = 'md', loading = false, disabled, children, className = '', ...rest }) {
15
- return (_jsxs("button", { disabled: disabled || loading, className: `inline-flex items-center justify-center gap-2 rounded-[var(--radius)] font-medium transition-colors disabled:pointer-events-none disabled:opacity-50 ${variantClasses[variant]} ${sizeClasses[size]} ${className}`, ...rest, children: [loading && (_jsxs("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })] })), children] }));
16
- }
3
+ import { forwardRef } from 'react';
4
+ import { cv } from '../../lib/cv.js';
5
+ const button = cv(
6
+ // Base classes apply to every variant.
7
+ 'focus-visible:ring-offset-background inline-flex items-center justify-center gap-2 rounded-[var(--radius)] font-medium transition-colors focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50', {
8
+ variants: {
9
+ variant: {
10
+ primary: 'bg-[var(--primary)] text-[var(--primary-foreground)] hover:opacity-90',
11
+ secondary: 'bg-[var(--secondary)] text-[var(--secondary-foreground)] hover:opacity-80',
12
+ danger: 'bg-[var(--destructive)] text-[var(--destructive-foreground)] hover:opacity-90',
13
+ ghost: 'bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
14
+ outline: 'border border-[var(--border)] bg-transparent text-[var(--foreground)] hover:bg-[var(--accent)]',
15
+ link: 'bg-transparent text-[var(--primary)] underline-offset-4 hover:underline',
16
+ },
17
+ size: {
18
+ xs: 'h-7 px-2 text-xs',
19
+ sm: 'h-8 px-2.5 text-xs',
20
+ md: 'h-9 px-4 text-sm',
21
+ lg: 'h-10 px-6 text-base',
22
+ icon: 'h-9 w-9 p-0',
23
+ },
24
+ },
25
+ defaultVariants: {
26
+ variant: 'primary',
27
+ size: 'md',
28
+ },
29
+ });
30
+ export const Button = forwardRef(function Button({ variant, size, full, loading = false, disabled, leftIcon, rightIcon, children, className, ...rest }, ref) {
31
+ return (_jsxs("button", { ref: ref, disabled: disabled || loading, "aria-busy": loading || undefined, className: button({
32
+ variant,
33
+ size,
34
+ class: [full ? 'w-full' : '', className].filter(Boolean).join(' '),
35
+ }), ...rest, children: [loading ? (_jsxs("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", "aria-hidden": true, children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })] })) : (leftIcon), children, !loading && rightIcon] }));
36
+ });
37
+ export { button as buttonVariants };
17
38
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/components/ui/Button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAcZ,MAAM,cAAc,GAAkC;IACpD,OAAO,EAAE,uEAAuE;IAChF,SAAS,EAAE,2EAA2E;IACtF,MAAM,EAAE,+EAA+E;IACvF,KAAK,EAAE,kEAAkE;CAC1E,CAAA;AAED,MAAM,WAAW,GAA+B;IAC9C,EAAE,EAAE,qBAAqB;IACzB,EAAE,EAAE,mBAAmB;IACvB,EAAE,EAAE,uBAAuB;CAC5B,CAAA;AAED,MAAM,UAAU,MAAM,CAAC,EACrB,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,IAAI,EACX,OAAO,GAAG,KAAK,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,GAAG,EAAE,EACd,GAAG,IAAI,EACK;IACZ,OAAO,CACL,kBACE,QAAQ,EAAE,QAAQ,IAAI,OAAO,EAC7B,SAAS,EAAE,wJAAwJ,cAAc,CAAC,OAAO,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,SAAS,EAAE,KAC1N,IAAI,aAEP,OAAO,IAAI,CACV,eAAK,SAAS,EAAC,sBAAsB,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aACnE,iBACE,SAAS,EAAC,YAAY,EACtB,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,CAAC,EAAC,IAAI,EACN,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,GACf,EACF,eACE,SAAS,EAAC,YAAY,EACtB,IAAI,EAAC,cAAc,EACnB,CAAC,EAAC,qCAAqC,GACvC,IACE,CACP,EACA,QAAQ,IACF,CACV,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Button.js","sourceRoot":"","sources":["../../../src/components/ui/Button.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,UAAU,EAA6C,MAAM,OAAO,CAAA;AAC7E,OAAO,EAAE,EAAE,EAAqB,MAAM,iBAAiB,CAAA;AAEvD,MAAM,MAAM,GAAG,EAAE;AACf,uCAAuC;AACvC,wSAAwS,EACxS;IACE,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,OAAO,EAAE,uEAAuE;YAChF,SAAS,EAAE,2EAA2E;YACtF,MAAM,EAAE,+EAA+E;YACvF,KAAK,EAAE,kEAAkE;YACzE,OAAO,EACL,gGAAgG;YAClG,IAAI,EAAE,yEAAyE;SAChF;QACD,IAAI,EAAE;YACJ,EAAE,EAAE,kBAAkB;YACtB,EAAE,EAAE,oBAAoB;YACxB,EAAE,EAAE,kBAAkB;YACtB,EAAE,EAAE,qBAAqB;YACzB,IAAI,EAAE,aAAa;SACpB;KACF;IACD,eAAe,EAAE;QACf,OAAO,EAAE,SAAS;QAClB,IAAI,EAAE,IAAI;KACX;CACF,CACF,CAAA;AAeD,MAAM,CAAC,MAAM,MAAM,GAAG,UAAU,CAAiC,SAAS,MAAM,CAC9E,EACE,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,OAAO,GAAG,KAAK,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,EACD,GAAG;IAEH,OAAO,CACL,kBACE,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,QAAQ,IAAI,OAAO,eAClB,OAAO,IAAI,SAAS,EAC/B,SAAS,EAAE,MAAM,CAAC;YAChB,OAAO;YACP,IAAI;YACJ,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;SACnE,CAAC,KACE,IAAI,aAEP,OAAO,CAAC,CAAC,CAAC,CACT,eAAK,SAAS,EAAC,sBAAsB,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,kCACnE,iBACE,SAAS,EAAC,YAAY,EACtB,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,CAAC,EAAC,IAAI,EACN,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,GACf,EACF,eACE,SAAS,EAAC,YAAY,EACtB,IAAI,EAAC,cAAc,EACnB,CAAC,EAAC,qCAAqC,GACvC,IACE,CACP,CAAC,CAAC,CAAC,CACF,QAAQ,CACT,EACA,QAAQ,EACR,CAAC,OAAO,IAAI,SAAS,IACf,CACV,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,CAAA"}
@@ -0,0 +1,26 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import { type VariantProps } from '../../lib/cv.js';
3
+ declare const card: (props?: ({
4
+ padding?: "none" | "sm" | "md" | "lg" | undefined;
5
+ elevation?: "flat" | "sm" | "md" | "lg" | undefined;
6
+ } & {
7
+ class?: string | false | null | undefined;
8
+ className?: string | false | null | undefined;
9
+ }) | undefined) => string;
10
+ export type CardVariants = VariantProps<typeof card>;
11
+ export interface CardProps extends HTMLAttributes<HTMLDivElement>, CardVariants {
12
+ /** Apply hover/focus elevation transitions (e.g. for clickable cards). */
13
+ interactive?: boolean;
14
+ children?: ReactNode;
15
+ }
16
+ export declare const Card: import("react").ForwardRefExoticComponent<CardProps & import("react").RefAttributes<HTMLDivElement>>;
17
+ /**
18
+ * Header slot — sits at the top of a card. Pair with CardTitle / CardDescription.
19
+ */
20
+ export declare function CardHeader({ className, children, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
21
+ export declare function CardTitle({ className, children, ...rest }: HTMLAttributes<HTMLHeadingElement>): import("react/jsx-runtime").JSX.Element;
22
+ export declare function CardDescription({ className, children, ...rest }: HTMLAttributes<HTMLParagraphElement>): import("react/jsx-runtime").JSX.Element;
23
+ export declare function CardContent({ className, children, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
24
+ export declare function CardFooter({ className, children, ...rest }: HTMLAttributes<HTMLDivElement>): import("react/jsx-runtime").JSX.Element;
25
+ export { card as cardVariants };
26
+ //# sourceMappingURL=Card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/ui/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACvE,OAAO,EAAM,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAEvD,QAAA,MAAM,IAAI;;;;;;yBAmBT,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,OAAO,IAAI,CAAC,CAAA;AAIpD,MAAM,WAAW,SAAU,SAAQ,cAAc,CAAC,cAAc,CAAC,EAAE,YAAY;IAC7E,0EAA0E;IAC1E,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,eAAO,MAAM,IAAI,sGAUf,CAAA;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,SAAc,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,2CAM/F;AAED,wBAAgB,SAAS,CAAC,EACxB,SAAc,EACd,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,kBAAkB,CAAC,2CASpC;AAED,wBAAgB,eAAe,CAAC,EAC9B,SAAc,EACd,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,cAAc,CAAC,oBAAoB,CAAC,2CAMtC;AAED,wBAAgB,WAAW,CAAC,EAAE,SAAc,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,2CAMhG;AAED,wBAAgB,UAAU,CAAC,EAAE,SAAc,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,2CAM/F;AAED,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,CAAA"}