@actuate-media/cms-admin 0.9.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (294) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +8 -5
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/layout/primitives.test.d.ts +2 -0
  5. package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
  6. package/dist/__tests__/layout/primitives.test.js +34 -0
  7. package/dist/__tests__/layout/primitives.test.js.map +1 -0
  8. package/dist/__tests__/lib/cv.test.d.ts +2 -0
  9. package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
  10. package/dist/__tests__/lib/cv.test.js +66 -0
  11. package/dist/__tests__/lib/cv.test.js.map +1 -0
  12. package/dist/actuate-admin.css +1 -1
  13. package/dist/assets/actuate-logo.d.ts +36 -0
  14. package/dist/assets/actuate-logo.d.ts.map +1 -0
  15. package/dist/assets/actuate-logo.js +15 -0
  16. package/dist/assets/actuate-logo.js.map +1 -0
  17. package/dist/components/Breadcrumbs.js +2 -2
  18. package/dist/components/CommandPalette.js +10 -10
  19. package/dist/components/ContentOverviewChart.js +3 -3
  20. package/dist/components/ErrorBoundary.js +1 -1
  21. package/dist/components/FocalPointPicker.js +2 -2
  22. package/dist/components/FolderTree.js +20 -20
  23. package/dist/components/LivePreview.js +3 -3
  24. package/dist/components/LocaleSwitcher.js +1 -1
  25. package/dist/components/MediaPickerModal.js +4 -4
  26. package/dist/components/PresenceIndicator.js +1 -1
  27. package/dist/components/SEOConfigPanel.d.ts +2 -0
  28. package/dist/components/SEOConfigPanel.d.ts.map +1 -0
  29. package/dist/components/SEOConfigPanel.js +174 -0
  30. package/dist/components/SEOConfigPanel.js.map +1 -0
  31. package/dist/components/SEOPanel.js +9 -9
  32. package/dist/components/SEOPerformance.js +2 -2
  33. package/dist/components/SchedulePublishDialog.d.ts +18 -0
  34. package/dist/components/SchedulePublishDialog.d.ts.map +1 -0
  35. package/dist/components/SchedulePublishDialog.js +106 -0
  36. package/dist/components/SchedulePublishDialog.js.map +1 -0
  37. package/dist/components/SharePreviewLinkDialog.d.ts +17 -0
  38. package/dist/components/SharePreviewLinkDialog.d.ts.map +1 -0
  39. package/dist/components/SharePreviewLinkDialog.js +83 -0
  40. package/dist/components/SharePreviewLinkDialog.js.map +1 -0
  41. package/dist/components/TipTapEditor.js +5 -5
  42. package/dist/components/VersionHistory.js +2 -2
  43. package/dist/components/ui/Badge.d.ts +33 -3
  44. package/dist/components/ui/Badge.d.ts.map +1 -1
  45. package/dist/components/ui/Badge.js +42 -8
  46. package/dist/components/ui/Badge.js.map +1 -1
  47. package/dist/components/ui/Button.d.ts +19 -8
  48. package/dist/components/ui/Button.d.ts.map +1 -1
  49. package/dist/components/ui/Button.js +35 -14
  50. package/dist/components/ui/Button.js.map +1 -1
  51. package/dist/components/ui/Card.d.ts +26 -0
  52. package/dist/components/ui/Card.d.ts.map +1 -0
  53. package/dist/components/ui/Card.js +45 -0
  54. package/dist/components/ui/Card.js.map +1 -0
  55. package/dist/components/ui/DataTable.js +1 -1
  56. package/dist/components/ui/Input.d.ts +15 -0
  57. package/dist/components/ui/Input.d.ts.map +1 -0
  58. package/dist/components/ui/Input.js +23 -0
  59. package/dist/components/ui/Input.js.map +1 -0
  60. package/dist/components/ui/SearchInput.js +1 -1
  61. package/dist/components/ui/Select.d.ts +16 -0
  62. package/dist/components/ui/Select.d.ts.map +1 -0
  63. package/dist/components/ui/Select.js +25 -0
  64. package/dist/components/ui/Select.js.map +1 -0
  65. package/dist/components/ui/Toast.js +1 -1
  66. package/dist/components/ui/index.d.ts +10 -4
  67. package/dist/components/ui/index.d.ts.map +1 -1
  68. package/dist/components/ui/index.js +5 -2
  69. package/dist/components/ui/index.js.map +1 -1
  70. package/dist/fields/BlockBuilderField.js +3 -3
  71. package/dist/fields/DateField.js +1 -1
  72. package/dist/fields/RelationshipField.js +3 -3
  73. package/dist/fields/TextField.js +1 -1
  74. package/dist/index.d.ts +6 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +5 -0
  77. package/dist/index.js.map +1 -1
  78. package/dist/layout/Header.js +1 -1
  79. package/dist/layout/Layout.d.ts +14 -0
  80. package/dist/layout/Layout.d.ts.map +1 -1
  81. package/dist/layout/Layout.js +17 -11
  82. package/dist/layout/Layout.js.map +1 -1
  83. package/dist/layout/Sidebar.d.ts.map +1 -1
  84. package/dist/layout/Sidebar.js +21 -11
  85. package/dist/layout/Sidebar.js.map +1 -1
  86. package/dist/layout/primitives/AdminShell.d.ts +43 -0
  87. package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
  88. package/dist/layout/primitives/AdminShell.js +51 -0
  89. package/dist/layout/primitives/AdminShell.js.map +1 -0
  90. package/dist/layout/primitives/Box.d.ts +19 -0
  91. package/dist/layout/primitives/Box.d.ts.map +1 -0
  92. package/dist/layout/primitives/Box.js +12 -0
  93. package/dist/layout/primitives/Box.js.map +1 -0
  94. package/dist/layout/primitives/Cluster.d.ts +27 -0
  95. package/dist/layout/primitives/Cluster.d.ts.map +1 -0
  96. package/dist/layout/primitives/Cluster.js +37 -0
  97. package/dist/layout/primitives/Cluster.js.map +1 -0
  98. package/dist/layout/primitives/Grid.d.ts +45 -0
  99. package/dist/layout/primitives/Grid.d.ts.map +1 -0
  100. package/dist/layout/primitives/Grid.js +59 -0
  101. package/dist/layout/primitives/Grid.js.map +1 -0
  102. package/dist/layout/primitives/PageContainer.d.ts +36 -0
  103. package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
  104. package/dist/layout/primitives/PageContainer.js +41 -0
  105. package/dist/layout/primitives/PageContainer.js.map +1 -0
  106. package/dist/layout/primitives/Split.d.ts +34 -0
  107. package/dist/layout/primitives/Split.d.ts.map +1 -0
  108. package/dist/layout/primitives/Split.js +27 -0
  109. package/dist/layout/primitives/Split.js.map +1 -0
  110. package/dist/layout/primitives/Stack.d.ts +23 -0
  111. package/dist/layout/primitives/Stack.d.ts.map +1 -0
  112. package/dist/layout/primitives/Stack.js +34 -0
  113. package/dist/layout/primitives/Stack.js.map +1 -0
  114. package/dist/layout/primitives/index.d.ts +30 -0
  115. package/dist/layout/primitives/index.d.ts.map +1 -0
  116. package/dist/layout/primitives/index.js +22 -0
  117. package/dist/layout/primitives/index.js.map +1 -0
  118. package/dist/layout/primitives/tokens.d.ts +48 -0
  119. package/dist/layout/primitives/tokens.d.ts.map +1 -0
  120. package/dist/layout/primitives/tokens.js +54 -0
  121. package/dist/layout/primitives/tokens.js.map +1 -0
  122. package/dist/lib/cv.d.ts +53 -0
  123. package/dist/lib/cv.d.ts.map +1 -0
  124. package/dist/lib/cv.js +39 -0
  125. package/dist/lib/cv.js.map +1 -0
  126. package/dist/views/ApiKeys.d.ts.map +1 -1
  127. package/dist/views/ApiKeys.js +13 -11
  128. package/dist/views/ApiKeys.js.map +1 -1
  129. package/dist/views/CollectionList.js +8 -8
  130. package/dist/views/Dashboard.d.ts.map +1 -1
  131. package/dist/views/Dashboard.js +333 -78
  132. package/dist/views/Dashboard.js.map +1 -1
  133. package/dist/views/DocumentEdit.d.ts.map +1 -1
  134. package/dist/views/DocumentEdit.js +17 -5
  135. package/dist/views/DocumentEdit.js.map +1 -1
  136. package/dist/views/ForgotPassword.js +2 -2
  137. package/dist/views/FormEditor.js +5 -5
  138. package/dist/views/FormSubmissions.js +6 -6
  139. package/dist/views/Forms.js +2 -2
  140. package/dist/views/Login.d.ts +16 -1
  141. package/dist/views/Login.d.ts.map +1 -1
  142. package/dist/views/Login.js +17 -7
  143. package/dist/views/Login.js.map +1 -1
  144. package/dist/views/MediaBrowser.js +16 -16
  145. package/dist/views/PageEditor.js +2 -2
  146. package/dist/views/Pages.js +10 -10
  147. package/dist/views/PostEditor.js +2 -2
  148. package/dist/views/Posts.js +4 -4
  149. package/dist/views/Redirects.js +4 -4
  150. package/dist/views/ResetPassword.js +2 -2
  151. package/dist/views/SEO.js +6 -6
  152. package/dist/views/ScriptTagEditor.js +4 -4
  153. package/dist/views/ScriptTags.js +2 -2
  154. package/dist/views/Settings.d.ts.map +1 -1
  155. package/dist/views/Settings.js +9 -8
  156. package/dist/views/Settings.js.map +1 -1
  157. package/dist/views/SetupWizard.js +2 -2
  158. package/dist/views/Users.js +4 -4
  159. package/dist/views/page-builder/AIBlockAssist.js +1 -1
  160. package/dist/views/page-builder/AIGenerateDialog.js +10 -10
  161. package/dist/views/page-builder/BlockEditor.js +10 -10
  162. package/dist/views/page-builder/BlockPicker.js +4 -4
  163. package/dist/views/page-builder/BottomBar.js +1 -1
  164. package/dist/views/page-builder/BuilderToolbar.js +2 -2
  165. package/dist/views/page-builder/ContextPanel.js +2 -2
  166. package/dist/views/page-builder/DesignScore.js +9 -9
  167. package/dist/views/page-builder/NodeSettings.js +8 -8
  168. package/dist/views/page-builder/PageBuilder.js +3 -3
  169. package/dist/views/page-builder/PageSettings.js +1 -1
  170. package/dist/views/page-builder/PageTemplates.js +2 -2
  171. package/dist/views/page-builder/SEOPanel.js +13 -13
  172. package/dist/views/page-builder/SavedSections.js +5 -5
  173. package/dist/views/page-builder/TemplatePicker.js +2 -2
  174. package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
  175. package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
  176. package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
  177. package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
  178. package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
  179. package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
  180. package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
  181. package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
  182. package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
  183. package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
  184. package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
  185. package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
  186. package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
  187. package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
  188. package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
  189. package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
  190. package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
  191. package/package.json +6 -2
  192. package/src/AdminRoot.tsx +21 -11
  193. package/src/__tests__/layout/primitives.test.ts +37 -0
  194. package/src/__tests__/lib/cv.test.ts +74 -0
  195. package/src/assets/actuate-logo.tsx +72 -0
  196. package/src/components/Breadcrumbs.tsx +6 -6
  197. package/src/components/CommandPalette.tsx +34 -34
  198. package/src/components/ContentOverviewChart.tsx +3 -3
  199. package/src/components/ErrorBoundary.tsx +3 -3
  200. package/src/components/FocalPointPicker.tsx +4 -4
  201. package/src/components/FolderTree.tsx +38 -38
  202. package/src/components/LivePreview.tsx +16 -16
  203. package/src/components/LocaleSwitcher.tsx +7 -7
  204. package/src/components/MediaPickerModal.tsx +21 -21
  205. package/src/components/PresenceIndicator.tsx +2 -2
  206. package/src/components/SEOConfigPanel.tsx +582 -0
  207. package/src/components/SEOPanel.tsx +46 -46
  208. package/src/components/SEOPerformance.tsx +21 -21
  209. package/src/components/SchedulePublishDialog.tsx +241 -0
  210. package/src/components/SharePreviewLinkDialog.tsx +227 -0
  211. package/src/components/TipTapEditor.tsx +33 -33
  212. package/src/components/VersionHistory.tsx +16 -16
  213. package/src/components/ui/Badge.tsx +66 -14
  214. package/src/components/ui/Button.tsx +70 -33
  215. package/src/components/ui/Card.tsx +101 -0
  216. package/src/components/ui/DataTable.tsx +1 -1
  217. package/src/components/ui/Input.tsx +35 -0
  218. package/src/components/ui/SearchInput.tsx +4 -4
  219. package/src/components/ui/Select.tsx +56 -0
  220. package/src/components/ui/Toast.tsx +1 -1
  221. package/src/components/ui/index.ts +18 -4
  222. package/src/fields/BlockBuilderField.tsx +3 -3
  223. package/src/fields/DateField.tsx +1 -1
  224. package/src/fields/RelationshipField.tsx +10 -10
  225. package/src/fields/TextField.tsx +1 -1
  226. package/src/index.ts +32 -0
  227. package/src/layout/Header.tsx +28 -28
  228. package/src/layout/Layout.tsx +39 -46
  229. package/src/layout/Sidebar.tsx +37 -64
  230. package/src/layout/primitives/AdminShell.tsx +118 -0
  231. package/src/layout/primitives/Box.tsx +30 -0
  232. package/src/layout/primitives/Cluster.tsx +74 -0
  233. package/src/layout/primitives/Grid.tsx +120 -0
  234. package/src/layout/primitives/PageContainer.tsx +96 -0
  235. package/src/layout/primitives/Split.tsx +73 -0
  236. package/src/layout/primitives/Stack.tsx +67 -0
  237. package/src/layout/primitives/index.ts +36 -0
  238. package/src/layout/primitives/tokens.ts +76 -0
  239. package/src/lib/cv.ts +96 -0
  240. package/src/styles/build-input.css +1 -1
  241. package/src/views/ApiKeys.tsx +57 -57
  242. package/src/views/CollectionList.tsx +30 -30
  243. package/src/views/Dashboard.tsx +737 -186
  244. package/src/views/DocumentEdit.tsx +90 -10
  245. package/src/views/ForgotPassword.tsx +18 -18
  246. package/src/views/FormEditor.tsx +75 -75
  247. package/src/views/FormSubmissions.tsx +76 -76
  248. package/src/views/Forms.tsx +27 -27
  249. package/src/views/Login.tsx +65 -25
  250. package/src/views/MediaBrowser.tsx +127 -127
  251. package/src/views/PageEditor.tsx +25 -25
  252. package/src/views/Pages.tsx +59 -59
  253. package/src/views/PostEditor.tsx +37 -37
  254. package/src/views/Posts.tsx +48 -48
  255. package/src/views/Redirects.tsx +21 -21
  256. package/src/views/ResetPassword.tsx +28 -28
  257. package/src/views/SEO.tsx +144 -144
  258. package/src/views/ScriptTagEditor.tsx +24 -24
  259. package/src/views/ScriptTags.tsx +10 -10
  260. package/src/views/Settings.tsx +88 -80
  261. package/src/views/SetupWizard.tsx +28 -28
  262. package/src/views/Users.tsx +20 -20
  263. package/src/views/page-builder/AIBlockAssist.tsx +1 -1
  264. package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
  265. package/src/views/page-builder/BlockEditor.tsx +26 -26
  266. package/src/views/page-builder/BlockPicker.tsx +22 -22
  267. package/src/views/page-builder/BottomBar.tsx +8 -8
  268. package/src/views/page-builder/BuilderToolbar.tsx +17 -17
  269. package/src/views/page-builder/ContextPanel.tsx +3 -3
  270. package/src/views/page-builder/DesignScore.tsx +21 -21
  271. package/src/views/page-builder/NodeSettings.tsx +27 -27
  272. package/src/views/page-builder/PageBuilder.tsx +11 -11
  273. package/src/views/page-builder/PageSettings.tsx +4 -4
  274. package/src/views/page-builder/PageTemplates.tsx +18 -18
  275. package/src/views/page-builder/SEOPanel.tsx +53 -53
  276. package/src/views/page-builder/SavedSections.tsx +37 -37
  277. package/src/views/page-builder/TemplatePicker.tsx +17 -17
  278. package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
  279. package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
  280. package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
  281. package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
  282. package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
  283. package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
  284. package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
  285. package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
  286. package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
  287. package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
  288. package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
  289. package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
  290. package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
  291. package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
  292. package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
  293. package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
  294. package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
@@ -130,68 +130,68 @@ export function FolderTree({ scope, selected, onSelect, itemCounts, totalCount,
130
130
  const isActive = isSelected({ type: 'folder', folderId: folder.id });
131
131
  const isDragOver = dragOverId === folder.id;
132
132
  const count = countForFolder(folder.id);
133
- return (_jsxs("div", { children: [_jsxs("div", { className: `group flex items-center gap-1 px-2 py-1.5 rounded-md cursor-pointer text-sm transition-colors ${isActive
134
- ? 'bg-blue-50 text-blue-700 font-medium'
133
+ return (_jsxs("div", { children: [_jsxs("div", { className: `group flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-sm transition-colors ${isActive
134
+ ? 'bg-blue-50 font-medium text-blue-700'
135
135
  : isDragOver
136
136
  ? 'bg-blue-100 ring-2 ring-blue-300'
137
137
  : 'text-gray-700 hover:bg-gray-100'}`, style: { paddingLeft: `${8 + depth * 16}px` }, onClick: () => onSelect({ type: 'folder', folderId: folder.id }), onContextMenu: (e) => {
138
138
  e.preventDefault();
139
139
  setContextMenu({ id: folder.id, x: e.clientX, y: e.clientY });
140
- }, onDragOver: (e) => handleDragOver(e, folder.id), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, folder.id), children: [_jsx("button", { type: "button", className: `p-0.5 rounded hover:bg-gray-200 transition-colors ${hasChildren ? '' : 'invisible'}`, onClick: (e) => {
140
+ }, onDragOver: (e) => handleDragOver(e, folder.id), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, folder.id), children: [_jsx("button", { type: "button", className: `rounded p-0.5 transition-colors hover:bg-gray-200 ${hasChildren ? '' : 'invisible'}`, onClick: (e) => {
141
141
  e.stopPropagation();
142
142
  toggleExpand(folder.id);
143
- }, children: isExpanded ? (_jsx(ChevronDown, { className: "w-3.5 h-3.5" })) : (_jsx(ChevronRight, { className: "w-3.5 h-3.5" })) }), isExpanded ? (_jsx(FolderOpen, { className: "w-4 h-4 text-blue-500 shrink-0" })) : (_jsx(FolderIcon, { className: "w-4 h-4 text-gray-400 shrink-0" })), editingId === folder.id ? (_jsx("input", { ref: editInputRef, type: "text", value: editName, onChange: (e) => setEditName(e.target.value), onBlur: () => handleRename(folder.id), onKeyDown: (e) => {
143
+ }, children: isExpanded ? (_jsx(ChevronDown, { className: "h-3.5 w-3.5" })) : (_jsx(ChevronRight, { className: "h-3.5 w-3.5" })) }), isExpanded ? (_jsx(FolderOpen, { className: "h-4 w-4 shrink-0 text-blue-500" })) : (_jsx(FolderIcon, { className: "h-4 w-4 shrink-0 text-gray-400" })), editingId === folder.id ? (_jsx("input", { ref: editInputRef, type: "text", value: editName, onChange: (e) => setEditName(e.target.value), onBlur: () => handleRename(folder.id), onKeyDown: (e) => {
144
144
  if (e.key === 'Enter')
145
145
  handleRename(folder.id);
146
146
  if (e.key === 'Escape')
147
147
  setEditingId(null);
148
- }, className: "flex-1 min-w-0 text-sm border border-blue-300 rounded px-1 py-0 focus:outline-none focus:ring-1 focus:ring-blue-500", onClick: (e) => e.stopPropagation() })) : (_jsx("span", { className: "flex-1 min-w-0 truncate", children: folder.name })), count !== undefined && !editingId && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: count })), _jsx("button", { type: "button", className: "p-0.5 rounded opacity-0 group-hover:opacity-100 hover:bg-gray-200 transition-all", onClick: (e) => {
148
+ }, className: "min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none", onClick: (e) => e.stopPropagation() })) : (_jsx("span", { className: "min-w-0 flex-1 truncate", children: folder.name })), count !== undefined && !editingId && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: count })), _jsx("button", { type: "button", className: "rounded p-0.5 opacity-0 transition-all group-hover:opacity-100 hover:bg-gray-200", onClick: (e) => {
149
149
  e.stopPropagation();
150
150
  setContextMenu({ id: folder.id, x: e.clientX, y: e.clientY });
151
- }, children: _jsx(MoreHorizontal, { className: "w-3.5 h-3.5 text-gray-500" }) })] }), isExpanded && (_jsxs("div", { children: [folder.children.map((child) => renderFolder(child, depth + 1)), creatingIn === folder.id && (_jsxs("div", { className: "flex items-center gap-1 px-2 py-1", style: { paddingLeft: `${24 + (depth + 1) * 16}px` }, children: [_jsx(FolderIcon, { className: "w-4 h-4 text-gray-400 shrink-0" }), _jsx("input", { ref: newFolderInputRef, type: "text", value: newFolderName, onChange: (e) => setNewFolderName(e.target.value), onBlur: () => handleCreate(folder.id), onKeyDown: (e) => {
151
+ }, children: _jsx(MoreHorizontal, { className: "h-3.5 w-3.5 text-gray-500" }) })] }), isExpanded && (_jsxs("div", { children: [folder.children.map((child) => renderFolder(child, depth + 1)), creatingIn === folder.id && (_jsxs("div", { className: "flex items-center gap-1 px-2 py-1", style: { paddingLeft: `${24 + (depth + 1) * 16}px` }, children: [_jsx(FolderIcon, { className: "h-4 w-4 shrink-0 text-gray-400" }), _jsx("input", { ref: newFolderInputRef, type: "text", value: newFolderName, onChange: (e) => setNewFolderName(e.target.value), onBlur: () => handleCreate(folder.id), onKeyDown: (e) => {
152
152
  if (e.key === 'Enter')
153
153
  handleCreate(folder.id);
154
154
  if (e.key === 'Escape') {
155
155
  setCreatingIn(false);
156
156
  setNewFolderName('');
157
157
  }
158
- }, placeholder: "Folder name...", className: "flex-1 min-w-0 text-sm border border-blue-300 rounded px-1 py-0 focus:outline-none focus:ring-1 focus:ring-blue-500" })] }))] }))] }, folder.id));
158
+ }, placeholder: "Folder name...", className: "min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none" })] }))] }))] }, folder.id));
159
159
  };
160
160
  if (loading) {
161
- return (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Loader2, { className: "w-5 h-5 animate-spin text-gray-400" }) }));
161
+ return (_jsx("div", { className: "flex items-center justify-center py-8", children: _jsx(Loader2, { className: "h-5 w-5 animate-spin text-gray-400" }) }));
162
162
  }
163
- return (_jsxs("div", { className: "flex flex-col h-full", children: [_jsxs("div", { className: "space-y-0.5 px-1 py-2", children: [_jsxs("button", { type: "button", className: `w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-sm transition-colors ${isSelected({ type: 'smart', smart: 'all' })
164
- ? 'bg-blue-50 text-blue-700 font-medium'
165
- : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'all' }), onDragOver: (e) => handleDragOver(e, null), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, null), children: [_jsx(LayoutGrid, { className: "w-4 h-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "All" }), totalCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: totalCount }))] }), _jsxs("button", { type: "button", className: `w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-sm transition-colors ${isSelected({ type: 'smart', smart: 'recent' })
166
- ? 'bg-blue-50 text-blue-700 font-medium'
167
- : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'recent' }), children: [_jsx(Clock, { className: "w-4 h-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "Recent" }), recentCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: recentCount }))] }), _jsxs("button", { type: "button", className: `w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-sm transition-colors ${isSelected({ type: 'smart', smart: 'uncategorized' })
168
- ? 'bg-blue-50 text-blue-700 font-medium'
169
- : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'uncategorized' }), children: [_jsx(Inbox, { className: "w-4 h-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "Uncategorized" }), uncategorizedCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: uncategorizedCount }))] })] }), _jsx("div", { className: "border-t border-gray-200 my-1" }), _jsxs("div", { className: "flex-1 overflow-y-auto px-1 py-1 space-y-0.5", children: [folders.map((folder) => renderFolder(folder, 0)), creatingIn === null && (_jsxs("div", { className: "flex items-center gap-1 px-2 py-1", children: [_jsx(FolderIcon, { className: "w-4 h-4 text-gray-400 shrink-0 ml-5" }), _jsx("input", { ref: newFolderInputRef, type: "text", value: newFolderName, onChange: (e) => setNewFolderName(e.target.value), onBlur: () => handleCreate(null), onKeyDown: (e) => {
163
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "space-y-0.5 px-1 py-2", children: [_jsxs("button", { type: "button", className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${isSelected({ type: 'smart', smart: 'all' })
164
+ ? 'bg-blue-50 font-medium text-blue-700'
165
+ : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'all' }), onDragOver: (e) => handleDragOver(e, null), onDragLeave: handleDragLeave, onDrop: (e) => handleDrop(e, null), children: [_jsx(LayoutGrid, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "All" }), totalCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: totalCount }))] }), _jsxs("button", { type: "button", className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${isSelected({ type: 'smart', smart: 'recent' })
166
+ ? 'bg-blue-50 font-medium text-blue-700'
167
+ : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'recent' }), children: [_jsx(Clock, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "Recent" }), recentCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: recentCount }))] }), _jsxs("button", { type: "button", className: `flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${isSelected({ type: 'smart', smart: 'uncategorized' })
168
+ ? 'bg-blue-50 font-medium text-blue-700'
169
+ : 'text-gray-700 hover:bg-gray-100'}`, onClick: () => onSelect({ type: 'smart', smart: 'uncategorized' }), children: [_jsx(Inbox, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "flex-1 text-left", children: "Uncategorized" }), uncategorizedCount !== undefined && (_jsx("span", { className: "text-xs text-gray-400 tabular-nums", children: uncategorizedCount }))] })] }), _jsx("div", { className: "my-1 border-t border-gray-200" }), _jsxs("div", { className: "flex-1 space-y-0.5 overflow-y-auto px-1 py-1", children: [folders.map((folder) => renderFolder(folder, 0)), creatingIn === null && (_jsxs("div", { className: "flex items-center gap-1 px-2 py-1", children: [_jsx(FolderIcon, { className: "ml-5 h-4 w-4 shrink-0 text-gray-400" }), _jsx("input", { ref: newFolderInputRef, type: "text", value: newFolderName, onChange: (e) => setNewFolderName(e.target.value), onBlur: () => handleCreate(null), onKeyDown: (e) => {
170
170
  if (e.key === 'Enter')
171
171
  handleCreate(null);
172
172
  if (e.key === 'Escape') {
173
173
  setCreatingIn(false);
174
174
  setNewFolderName('');
175
175
  }
176
- }, placeholder: "Folder name...", className: "flex-1 min-w-0 text-sm border border-blue-300 rounded px-1 py-0 focus:outline-none focus:ring-1 focus:ring-blue-500" })] }))] }), _jsx("div", { className: "border-t border-gray-200 p-2", children: _jsxs("button", { type: "button", onClick: () => {
176
+ }, placeholder: "Folder name...", className: "min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none" })] }))] }), _jsx("div", { className: "border-t border-gray-200 p-2", children: _jsxs("button", { type: "button", onClick: () => {
177
177
  setCreatingIn(null);
178
178
  setNewFolderName('');
179
- }, className: "w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-sm text-gray-600 hover:bg-gray-100 transition-colors", children: [_jsx(Plus, { className: "w-4 h-4" }), "New Folder"] }) }), contextMenu && (_jsxs("div", { className: "fixed z-50 bg-white rounded-lg border border-gray-200 shadow-lg py-1 min-w-[160px]", style: { left: contextMenu.x, top: contextMenu.y }, children: [_jsxs("button", { type: "button", className: "w-full flex items-center gap-2 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 transition-colors", onClick: () => {
179
+ }, className: "flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm text-gray-600 transition-colors hover:bg-gray-100", children: [_jsx(Plus, { className: "h-4 w-4" }), "New Folder"] }) }), contextMenu && (_jsxs("div", { className: "fixed z-50 min-w-[160px] rounded-lg border border-gray-200 bg-white py-1 shadow-lg", style: { left: contextMenu.x, top: contextMenu.y }, children: [_jsxs("button", { type: "button", className: "flex w-full items-center gap-2 px-3 py-1.5 text-sm text-gray-700 transition-colors hover:bg-gray-100", onClick: () => {
180
180
  const folder = findFolder(folders, contextMenu.id);
181
181
  if (folder) {
182
182
  setEditingId(folder.id);
183
183
  setEditName(folder.name);
184
184
  }
185
185
  setContextMenu(null);
186
- }, children: [_jsx(Pencil, { className: "w-3.5 h-3.5" }), "Rename"] }), _jsxs("button", { type: "button", className: "w-full flex items-center gap-2 px-3 py-1.5 text-sm text-gray-700 hover:bg-gray-100 transition-colors", onClick: () => {
186
+ }, children: [_jsx(Pencil, { className: "h-3.5 w-3.5" }), "Rename"] }), _jsxs("button", { type: "button", className: "flex w-full items-center gap-2 px-3 py-1.5 text-sm text-gray-700 transition-colors hover:bg-gray-100", onClick: () => {
187
187
  setCreatingIn(contextMenu.id);
188
188
  setNewFolderName('');
189
189
  setExpanded((prev) => new Set(prev).add(contextMenu.id));
190
190
  setContextMenu(null);
191
- }, children: [_jsx(FolderPlus, { className: "w-3.5 h-3.5" }), "New Subfolder"] }), _jsx("div", { className: "border-t border-gray-200 my-1" }), _jsxs("button", { type: "button", className: "w-full flex items-center gap-2 px-3 py-1.5 text-sm text-red-600 hover:bg-red-50 transition-colors", onClick: () => {
191
+ }, children: [_jsx(FolderPlus, { className: "h-3.5 w-3.5" }), "New Subfolder"] }), _jsx("div", { className: "my-1 border-t border-gray-200" }), _jsxs("button", { type: "button", className: "flex w-full items-center gap-2 px-3 py-1.5 text-sm text-red-600 transition-colors hover:bg-red-50", onClick: () => {
192
192
  handleDelete(contextMenu.id);
193
193
  setContextMenu(null);
194
- }, children: [_jsx(Trash2, { className: "w-3.5 h-3.5" }), "Delete"] })] }))] }));
194
+ }, children: [_jsx(Trash2, { className: "h-3.5 w-3.5" }), "Delete"] })] }))] }));
195
195
  }
196
196
  function findFolder(nodes, id) {
197
197
  for (const n of nodes) {
@@ -53,14 +53,14 @@ export function LivePreview({ collection, documentId, previewUrl, values, onClos
53
53
  window.open(previewSrc, '_blank');
54
54
  }, [previewSrc]);
55
55
  if (!previewSrc) {
56
- return (_jsxs("div", { className: "flex flex-col items-center justify-center h-full bg-gray-50 rounded-lg border border-dashed border-gray-300 p-8", children: [_jsx("p", { className: "text-sm text-gray-500 text-center", children: !documentId
56
+ return (_jsxs("div", { className: "flex h-full flex-col items-center justify-center rounded-lg border border-dashed border-gray-300 bg-gray-50 p-8", children: [_jsx("p", { className: "text-center text-sm text-gray-500", children: !documentId
57
57
  ? 'Save the document first to enable preview'
58
58
  : 'Configure a preview URL in the collection settings to enable live preview' }), _jsx("button", { onClick: onClose, className: "mt-4 text-xs text-gray-400 hover:text-gray-600", children: "Close Preview" })] }));
59
59
  }
60
- return (_jsxs("div", { className: "flex flex-col h-full border-l border-gray-200 bg-white", children: [_jsxs("div", { className: "flex items-center justify-between px-3 py-2 border-b border-gray-200 bg-gray-50", children: [_jsx("div", { className: "flex items-center gap-1", children: [
60
+ return (_jsxs("div", { className: "flex h-full flex-col border-l border-gray-200 bg-white", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 bg-gray-50 px-3 py-2", children: [_jsx("div", { className: "flex items-center gap-1", children: [
61
61
  ['desktop', Monitor],
62
62
  ['tablet', Tablet],
63
63
  ['mobile', Smartphone],
64
- ].map(([vp, Icon]) => (_jsx("button", { onClick: () => setViewport(vp), className: `p-1.5 rounded ${viewport === vp ? 'bg-white shadow-sm text-blue-600' : 'text-gray-400 hover:text-gray-600'}`, title: vp, children: _jsx(Icon, { className: "w-4 h-4" }) }, vp))) }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: handleRefresh, className: "p-1.5 rounded text-gray-400 hover:text-gray-600", title: "Refresh", children: _jsx(RefreshCw, { className: "w-4 h-4" }) }), _jsx("button", { onClick: handleOpenExternal, className: "p-1.5 rounded text-gray-400 hover:text-gray-600", title: "Open in new tab", children: _jsx(ExternalLink, { className: "w-4 h-4" }) }), _jsx("button", { onClick: onClose, className: "p-1.5 rounded text-gray-400 hover:text-gray-600", title: "Close", children: _jsx(X, { className: "w-4 h-4" }) })] })] }), _jsx("div", { className: "flex-1 overflow-auto flex justify-center bg-gray-100 p-4", children: _jsxs("div", { style: { width: VIEWPORT_WIDTHS[viewport], maxWidth: '100%', transition: 'width 0.3s' }, className: "relative", children: [loading && (_jsx("div", { className: "absolute inset-0 flex items-center justify-center bg-white/80 z-10 rounded-lg", children: _jsx("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600" }) })), _jsx("iframe", { ref: iframeRef, src: previewSrc, className: "w-full h-full bg-white rounded-lg shadow-lg border border-gray-200", style: { minHeight: '600px' }, onLoad: () => setLoading(false), title: "Page Preview" })] }) })] }));
64
+ ].map(([vp, Icon]) => (_jsx("button", { onClick: () => setViewport(vp), className: `rounded p-1.5 ${viewport === vp ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-400 hover:text-gray-600'}`, title: vp, children: _jsx(Icon, { className: "h-4 w-4" }) }, vp))) }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: handleRefresh, className: "rounded p-1.5 text-gray-400 hover:text-gray-600", title: "Refresh", children: _jsx(RefreshCw, { className: "h-4 w-4" }) }), _jsx("button", { onClick: handleOpenExternal, className: "rounded p-1.5 text-gray-400 hover:text-gray-600", title: "Open in new tab", children: _jsx(ExternalLink, { className: "h-4 w-4" }) }), _jsx("button", { onClick: onClose, className: "rounded p-1.5 text-gray-400 hover:text-gray-600", title: "Close", children: _jsx(X, { className: "h-4 w-4" }) })] })] }), _jsx("div", { className: "flex flex-1 justify-center overflow-auto bg-gray-100 p-4", children: _jsxs("div", { style: { width: VIEWPORT_WIDTHS[viewport], maxWidth: '100%', transition: 'width 0.3s' }, className: "relative", children: [loading && (_jsx("div", { className: "absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-white/80", children: _jsx("div", { className: "h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600" }) })), _jsx("iframe", { ref: iframeRef, src: previewSrc, className: "h-full w-full rounded-lg border border-gray-200 bg-white shadow-lg", style: { minHeight: '600px' }, onLoad: () => setLoading(false), title: "Page Preview" })] }) })] }));
65
65
  }
66
66
  //# sourceMappingURL=LivePreview.js.map
@@ -8,6 +8,6 @@ export function LocaleSwitcher() {
8
8
  if (locales.length < 2)
9
9
  return null;
10
10
  const activeLabel = locales.find((l) => l.code === activeLocale)?.label ?? activeLocale;
11
- return (_jsxs(DropdownMenu.Root, { children: [_jsx(DropdownMenu.Trigger, { asChild: true, children: _jsxs("button", { className: "flex items-center gap-1.5 px-2 py-1.5 text-sm hover:bg-[var(--accent)] rounded-lg transition-colors", "aria-label": "Switch locale", children: [_jsx(Globe, { className: "w-4 h-4 text-[var(--muted-foreground)]" }), _jsx("span", { className: "hidden sm:inline text-[var(--foreground)] text-sm font-medium", children: activeLabel }), _jsx(ChevronDown, { className: "w-3 h-3 text-[var(--muted-foreground)]" })] }) }), _jsx(DropdownMenu.Portal, { children: _jsx(DropdownMenu.Content, { className: "min-w-[160px] bg-[var(--popover)] text-[var(--popover-foreground)] rounded-lg border border-[var(--border)] shadow-lg p-1 z-50", align: "end", sideOffset: 5, children: locales.map((locale) => (_jsxs(DropdownMenu.Item, { onSelect: () => setLocale(locale.code), className: "flex items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-[var(--accent)] rounded cursor-pointer outline-none", children: [_jsx("span", { children: locale.label }), locale.code === activeLocale && _jsx(Check, { className: "w-4 h-4 text-[var(--primary)]" })] }, locale.code))) }) })] }));
11
+ return (_jsxs(DropdownMenu.Root, { children: [_jsx(DropdownMenu.Trigger, { asChild: true, children: _jsxs("button", { className: "flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm transition-colors hover:bg-[var(--accent)]", "aria-label": "Switch locale", children: [_jsx(Globe, { className: "h-4 w-4 text-[var(--muted-foreground)]" }), _jsx("span", { className: "hidden text-sm font-medium text-[var(--foreground)] sm:inline", children: activeLabel }), _jsx(ChevronDown, { className: "h-3 w-3 text-[var(--muted-foreground)]" })] }) }), _jsx(DropdownMenu.Portal, { children: _jsx(DropdownMenu.Content, { className: "z-50 min-w-[160px] rounded-lg border border-[var(--border)] bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-lg", align: "end", sideOffset: 5, children: locales.map((locale) => (_jsxs(DropdownMenu.Item, { onSelect: () => setLocale(locale.code), className: "flex cursor-pointer items-center justify-between gap-2 rounded px-3 py-2 text-sm outline-none hover:bg-[var(--accent)]", children: [_jsx("span", { children: locale.label }), locale.code === activeLocale && _jsx(Check, { className: "h-4 w-4 text-[var(--primary)]" })] }, locale.code))) }) })] }));
12
12
  }
13
13
  //# sourceMappingURL=LocaleSwitcher.js.map
@@ -44,10 +44,10 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }) {
44
44
  }
45
45
  if (!open)
46
46
  return null;
47
- return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "fixed inset-0 bg-black/40", onClick: onClose }), _jsxs("div", { className: "relative bg-white rounded-xl shadow-2xl w-full max-w-2xl max-h-[80vh] flex flex-col mx-4", children: [_jsxs("div", { className: "flex items-center justify-between px-4 py-3 border-b border-gray-200", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Insert Image" }), _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" }) })] }), _jsxs("div", { className: "flex border-b border-gray-200", children: [_jsx("button", { onClick: () => setTab('library'), className: `flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${tab === 'library'
48
- ? 'text-blue-600 border-b-2 border-blue-600'
47
+ return (_jsxs("div", { className: "fixed inset-0 z-50 flex items-center justify-center", children: [_jsx("div", { className: "fixed inset-0 bg-black/40", onClick: onClose }), _jsxs("div", { className: "relative mx-4 flex max-h-[80vh] w-full max-w-2xl flex-col rounded-xl bg-white shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-4 py-3", children: [_jsx("h2", { className: "text-lg font-semibold text-gray-900", children: "Insert Image" }), _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: "flex border-b border-gray-200", children: [_jsx("button", { onClick: () => setTab('library'), className: `flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${tab === 'library'
48
+ ? 'border-b-2 border-blue-600 text-blue-600'
49
49
  : 'text-gray-500 hover:text-gray-700'}`, children: "Media Library" }), _jsx("button", { onClick: () => setTab('upload'), className: `flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${tab === 'upload'
50
- ? 'text-blue-600 border-b-2 border-blue-600'
51
- : 'text-gray-500 hover:text-gray-700'}`, children: "Upload New" })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-4", children: tab === 'library' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative mb-4", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Search images...", className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), loading ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-gray-400" }) })) : imageItems.length === 0 ? (_jsx("div", { className: "text-center py-12 text-sm text-gray-500", children: "No images found. Try uploading one." })) : (_jsx("div", { className: "grid grid-cols-3 sm:grid-cols-4 gap-3", children: imageItems.map((item) => (_jsxs("button", { onClick: () => handleSelectItem(item), className: "group relative aspect-square rounded-lg border-2 border-gray-200 hover:border-blue-500 overflow-hidden bg-gray-100 transition-colors", children: [_jsx("div", { className: "w-full h-full flex items-center justify-center", children: _jsx(ImageIcon, { className: "w-8 h-8 text-gray-300" }) }), _jsx("div", { className: "absolute inset-x-0 bottom-0 bg-black/60 p-1.5 opacity-0 group-hover:opacity-100 transition-opacity", children: _jsx("p", { className: "text-white text-xs truncate", children: item.filename }) })] }, item.id))) }))] })) : (_jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [_jsx("input", { ref: fileInputRef, type: "file", accept: accept ?? 'image/*', className: "hidden", onChange: (e) => handleUpload(e.target.files) }), _jsx("div", { className: "w-16 h-16 rounded-full bg-blue-50 flex items-center justify-center mb-4", children: uploading ? (_jsx(Loader2, { className: "w-8 h-8 text-blue-600 animate-spin" })) : (_jsx(Upload, { className: "w-8 h-8 text-blue-600" })) }), _jsx("p", { className: "text-sm text-gray-600 mb-4", children: uploading ? 'Uploading...' : 'Select an image file to upload' }), !uploading && (_jsx("button", { onClick: () => fileInputRef.current?.click(), className: "px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors", children: "Choose File" }))] })) })] })] }));
50
+ ? 'border-b-2 border-blue-600 text-blue-600'
51
+ : 'text-gray-500 hover:text-gray-700'}`, children: "Upload New" })] }), _jsx("div", { className: "flex-1 overflow-y-auto p-4", children: tab === 'library' ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative mb-4", children: [_jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" }), _jsx("input", { type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: "Search images...", className: "w-full rounded-lg border border-gray-300 py-2 pr-3 pl-9 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), loading ? (_jsx("div", { className: "flex items-center justify-center py-12", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-gray-400" }) })) : imageItems.length === 0 ? (_jsx("div", { className: "py-12 text-center text-sm text-gray-500", children: "No images found. Try uploading one." })) : (_jsx("div", { className: "grid grid-cols-3 gap-3 sm:grid-cols-4", children: imageItems.map((item) => (_jsxs("button", { onClick: () => handleSelectItem(item), className: "group relative aspect-square overflow-hidden rounded-lg border-2 border-gray-200 bg-gray-100 transition-colors hover:border-blue-500", children: [_jsx("div", { className: "flex h-full w-full items-center justify-center", children: _jsx(ImageIcon, { className: "h-8 w-8 text-gray-300" }) }), _jsx("div", { className: "absolute inset-x-0 bottom-0 bg-black/60 p-1.5 opacity-0 transition-opacity group-hover:opacity-100", children: _jsx("p", { className: "truncate text-xs text-white", children: item.filename }) })] }, item.id))) }))] })) : (_jsxs("div", { className: "flex flex-col items-center justify-center py-12", children: [_jsx("input", { ref: fileInputRef, type: "file", accept: accept ?? 'image/*', className: "hidden", onChange: (e) => handleUpload(e.target.files) }), _jsx("div", { className: "mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-blue-50", children: uploading ? (_jsx(Loader2, { className: "h-8 w-8 animate-spin text-blue-600" })) : (_jsx(Upload, { className: "h-8 w-8 text-blue-600" })) }), _jsx("p", { className: "mb-4 text-sm text-gray-600", children: uploading ? 'Uploading...' : 'Select an image file to upload' }), !uploading && (_jsx("button", { onClick: () => fileInputRef.current?.click(), className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: "Choose File" }))] })) })] })] }));
52
52
  }
53
53
  //# sourceMappingURL=MediaPickerModal.js.map
@@ -35,6 +35,6 @@ export function PresenceIndicator({ documentId, currentUserId }) {
35
35
  }, [documentId, currentUserId]);
36
36
  if (users.length === 0)
37
37
  return null;
38
- return (_jsxs("div", { className: "flex items-center gap-1", title: `${users.length} other editor(s) active`, children: [users.slice(0, 5).map((user, i) => (_jsx("div", { className: "w-7 h-7 rounded-full flex items-center justify-center text-white text-xs font-medium ring-2 ring-white", style: { backgroundColor: COLORS[i % COLORS.length] }, title: user.name, children: user.name.charAt(0).toUpperCase() }, user.userId))), users.length > 5 && (_jsxs("div", { className: "w-7 h-7 rounded-full flex items-center justify-center bg-muted text-muted-foreground text-xs font-medium ring-2 ring-white", children: ["+", users.length - 5] }))] }));
38
+ return (_jsxs("div", { className: "flex items-center gap-1", title: `${users.length} other editor(s) active`, children: [users.slice(0, 5).map((user, i) => (_jsx("div", { className: "flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium text-white ring-2 ring-white", style: { backgroundColor: COLORS[i % COLORS.length] }, title: user.name, children: user.name.charAt(0).toUpperCase() }, user.userId))), users.length > 5 && (_jsxs("div", { className: "bg-muted text-muted-foreground flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium ring-2 ring-white", children: ["+", users.length - 5] }))] }));
39
39
  }
40
40
  //# sourceMappingURL=PresenceIndicator.js.map
@@ -0,0 +1,2 @@
1
+ export declare function SEOConfigPanel(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=SEOConfigPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SEOConfigPanel.d.ts","sourceRoot":"","sources":["../../src/components/SEOConfigPanel.tsx"],"names":[],"mappings":"AAoFA,wBAAgB,cAAc,4CA+V7B"}
@@ -0,0 +1,174 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ /**
4
+ * Admin UI for editing the site-wide + per-collection SEO defaults that are
5
+ * normally defined in `actuate.config.ts`. The CMS merges code-level config
6
+ * with these DB-stored overrides, so any field left blank here falls back to
7
+ * the static config (shown as the placeholder).
8
+ *
9
+ * Wired in `Settings.tsx` as the "SEO" tab. Talks to `/seo/config` (GET + PUT).
10
+ */
11
+ import { Loader2, RefreshCw, Save, Globe, FileText } from 'lucide-react';
12
+ import { useEffect, useMemo, useState } from 'react';
13
+ import { toast } from 'sonner';
14
+ import { cmsApi } from '../lib/api.js';
15
+ const SCHEMA_TYPES = [
16
+ '',
17
+ 'WebPage',
18
+ 'Article',
19
+ 'BlogPosting',
20
+ 'NewsArticle',
21
+ 'Product',
22
+ 'Service',
23
+ 'LocalBusiness',
24
+ 'FAQPage',
25
+ 'JobPosting',
26
+ 'Event',
27
+ 'Recipe',
28
+ 'Person',
29
+ 'Organization',
30
+ ];
31
+ const CHANGE_FREQS = ['', 'always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'];
32
+ export function SEOConfigPanel() {
33
+ const [data, setData] = useState(null);
34
+ const [loading, setLoading] = useState(true);
35
+ const [saving, setSaving] = useState(false);
36
+ const [error, setError] = useState(null);
37
+ const [site, setSite] = useState({});
38
+ const [collections, setCollections] = useState({});
39
+ async function load() {
40
+ setLoading(true);
41
+ setError(null);
42
+ const res = await cmsApi('/seo/config', { method: 'GET' });
43
+ if (res.error || !res.data) {
44
+ setError(res.error ?? 'Failed to load SEO config');
45
+ setLoading(false);
46
+ return;
47
+ }
48
+ setData(res.data);
49
+ setSite(res.data.overrides?.site ?? {});
50
+ setCollections(res.data.overrides?.collections ?? {});
51
+ setLoading(false);
52
+ }
53
+ useEffect(() => {
54
+ void load();
55
+ }, []);
56
+ // Field-level placeholder = the static value from actuate.config.ts. The
57
+ // input value is whatever the admin has typed (or the saved override). Empty
58
+ // input + empty override means "fall back to static", which is the desired
59
+ // UX for an additive overrides panel.
60
+ const staticSite = data?.static?.site ?? {};
61
+ async function handleSave() {
62
+ setSaving(true);
63
+ // Strip empty strings so they unset back to the static default rather
64
+ // than persisting "" — the store treats "" as "no override".
65
+ const cleanSite = stripEmpty(site);
66
+ const cleanCollections = {};
67
+ for (const [slug, c] of Object.entries(collections)) {
68
+ const cleaned = stripEmpty(c);
69
+ if (Object.keys(cleaned).length > 0)
70
+ cleanCollections[slug] = cleaned;
71
+ }
72
+ const res = await cmsApi('/seo/config', {
73
+ method: 'PUT',
74
+ body: JSON.stringify({ site: cleanSite, collections: cleanCollections }),
75
+ });
76
+ if (res.error) {
77
+ toast.error(res.error);
78
+ }
79
+ else {
80
+ toast.success('SEO defaults saved');
81
+ await load();
82
+ }
83
+ setSaving(false);
84
+ }
85
+ function patchSite(key, value) {
86
+ setSite((prev) => ({ ...prev, [key]: value }));
87
+ }
88
+ function patchSiteRobots(key, value) {
89
+ setSite((prev) => ({ ...prev, robots: { ...(prev.robots ?? {}), [key]: value } }));
90
+ }
91
+ function patchSiteSitemap(key, value) {
92
+ setSite((prev) => ({ ...prev, sitemap: { ...(prev.sitemap ?? {}), [key]: value } }));
93
+ }
94
+ function patchSiteOg(key, value) {
95
+ setSite((prev) => ({ ...prev, ogImage: { ...(prev.ogImage ?? {}), [key]: value } }));
96
+ }
97
+ function patchCollection(slug, key, value) {
98
+ setCollections((prev) => ({
99
+ ...prev,
100
+ [slug]: { ...(prev[slug] ?? {}), [key]: value },
101
+ }));
102
+ }
103
+ function patchCollectionRobots(slug, key, value) {
104
+ setCollections((prev) => ({
105
+ ...prev,
106
+ [slug]: {
107
+ ...(prev[slug] ?? {}),
108
+ defaultRobots: { ...(prev[slug]?.defaultRobots ?? {}), [key]: value },
109
+ },
110
+ }));
111
+ }
112
+ const updatedAt = useMemo(() => {
113
+ // `updatedAt` is set by the server when overrides are persisted but isn't
114
+ // part of the declared `SeoConfigOverrides` shape. Cast through `unknown`
115
+ // so we can surface it in the UI without widening the type contract.
116
+ const ts = data?.overrides?.updatedAt;
117
+ if (!ts)
118
+ return null;
119
+ try {
120
+ return new Date(ts).toLocaleString();
121
+ }
122
+ catch {
123
+ return ts;
124
+ }
125
+ }, [data]);
126
+ if (loading) {
127
+ return (_jsxs("div", { className: "flex items-center gap-2 py-8 text-sm text-gray-600", children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), " Loading SEO defaults\u2026"] }));
128
+ }
129
+ if (error) {
130
+ return (_jsxs("div", { className: "rounded-lg border border-red-200 bg-red-50 p-4 text-sm text-red-700", children: [_jsx("div", { className: "mb-2 font-medium", children: "Failed to load SEO config" }), _jsx("div", { className: "font-mono text-xs", children: error }), _jsxs("button", { onClick: () => void load(), className: "mt-3 inline-flex items-center gap-1.5 rounded-md border border-red-300 bg-white px-3 py-1.5 text-xs font-medium text-red-700 hover:bg-red-100", children: [_jsx(RefreshCw, { className: "h-3.5 w-3.5" }), " Retry"] })] }));
131
+ }
132
+ return (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { children: [_jsxs("p", { className: "text-sm text-gray-600", children: ["Edit the SEO defaults that flow into", ' ', _jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5 text-[11px]", children: "/sitemap.xml" }), ",", ' ', _jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5 text-[11px]", children: "/robots.txt" }), ",", ' ', _jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5 text-[11px]", children: "/og.png" }), ", and the", ' ', _jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5 text-[11px]", children: "/resolve" }), " meta + JSON-LD response. Empty fields fall back to", ' ', _jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5 text-[11px]", children: "actuate.config.ts" }), "."] }), updatedAt && _jsxs("p", { className: "mt-1 text-xs text-gray-500", children: ["Last saved: ", updatedAt] })] }), _jsxs("button", { onClick: handleSave, disabled: saving, className: "inline-flex shrink-0 items-center gap-1.5 rounded-md bg-blue-600 px-3 py-1.5 text-sm font-medium text-white shadow-sm hover:bg-blue-700 disabled:opacity-50", children: [saving ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : _jsx(Save, { className: "h-4 w-4" }), "Save SEO defaults"] })] }), _jsxs("section", { className: "rounded-lg border border-gray-200 bg-white", children: [_jsxs("header", { className: "flex items-center gap-2 border-b border-gray-200 px-4 py-3", children: [_jsx(Globe, { className: "h-4 w-4 text-blue-600" }), _jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Site-wide defaults" })] }), _jsxs("div", { className: "grid grid-cols-1 gap-4 p-4 md:grid-cols-2", children: [_jsx(Field, { label: "Site URL", placeholder: staticSite.siteUrl ?? 'https://example.com', value: site.siteUrl ?? '', onChange: (v) => patchSite('siteUrl', v), hint: "Canonical origin used in sitemap URLs and JSON-LD." }), _jsx(Field, { label: "Site name", placeholder: staticSite.siteName ?? 'My Site', value: site.siteName ?? '', onChange: (v) => patchSite('siteName', v), hint: "Brand name in OG cards and Schema.org Organization." }), _jsx(Field, { label: "Default OG image", placeholder: staticSite.defaultOgImage ?? '/og-default.png', value: site.defaultOgImage ?? '', onChange: (v) => patchSite('defaultOgImage', v), hint: "Used when a document doesn't supply its own." }), _jsx(Field, { label: "Twitter handle", placeholder: staticSite.twitterHandle ?? '@yourbrand', value: site.twitterHandle ?? '', onChange: (v) => patchSite('twitterHandle', v), hint: "Including the leading @." })] }), _jsxs("div", { className: "grid grid-cols-1 gap-4 border-t border-gray-100 p-4 md:grid-cols-3", children: [_jsx(Select, { label: "Default change frequency", value: site.sitemap?.defaultChangeFreq ?? '', options: CHANGE_FREQS, onChange: (v) => patchSiteSitemap('defaultChangeFreq', v), placeholderLabel: `default: ${staticSite.sitemap?.defaultChangeFreq ?? 'weekly'}`, hint: "Applied per-URL in sitemap.xml when a collection doesn't override." }), _jsx(NumberField, { label: "Default priority", value: site.sitemap?.defaultPriority, placeholder: `default: ${staticSite.sitemap?.defaultPriority ?? 0.6}`, onChange: (v) => patchSiteSitemap('defaultPriority', v), min: 0, max: 1, step: 0.1, hint: "Between 0.0 and 1.0." }), _jsx(Select, { label: "OG image theme", value: site.ogImage?.theme ?? '', options: ['', 'light', 'dark'], onChange: (v) => patchSiteOg('theme', (v || undefined)), placeholderLabel: `default: ${staticSite.ogImage?.theme ?? 'light'}`, hint: "Applied by the built-in /og.png renderer." })] }), _jsxs("div", { className: "flex flex-wrap gap-6 border-t border-gray-100 p-4", children: [_jsx(Toggle, { label: "Block known AI bots in robots.txt", checked: !!site.robots?.blockAIBots, onChange: (v) => patchSiteRobots('blockAIBots', v), hint: "GPTBot, ClaudeBot, anthropic-ai, Bytespider, etc." }), _jsx(Toggle, { label: "Disable robots.txt route", checked: !!site.robots?.disabled, onChange: (v) => patchSiteRobots('disabled', v) }), _jsx(Toggle, { label: "Disable sitemap.xml route", checked: !!site.sitemap?.disabled, onChange: (v) => patchSiteSitemap('disabled', v) }), _jsx(Toggle, { label: "Disable /og.png route", checked: !!site.ogImage?.disabled, onChange: (v) => patchSiteOg('disabled', v) })] })] }), _jsxs("section", { className: "rounded-lg border border-gray-200 bg-white", children: [_jsxs("header", { className: "flex items-center gap-2 border-b border-gray-200 px-4 py-3", children: [_jsx(FileText, { className: "h-4 w-4 text-blue-600" }), _jsx("h3", { className: "text-sm font-semibold text-gray-900", children: "Per-collection defaults" }), _jsx("span", { className: "text-xs text-gray-500", children: "\u2014 shown placeholders are the static defaults" })] }), _jsxs("div", { className: "divide-y divide-gray-100", children: [data?.collections.map((col) => {
133
+ const override = collections[col.slug] ?? {};
134
+ const staticC = col.staticSeo ?? {};
135
+ return (_jsxs("div", { className: "p-4", children: [_jsx("div", { className: "mb-3 flex items-baseline justify-between gap-4", children: _jsxs("div", { children: [_jsx("h4", { className: "text-sm font-semibold text-gray-900", children: col.label }), _jsxs("p", { className: "text-xs text-gray-500", children: [_jsx("code", { className: "rounded bg-gray-100 px-1 py-0.5", children: col.slug }), col.urlPrefix !== undefined && (_jsxs(_Fragment, { children: [' ', "prefix:", ' ', _jsxs("code", { className: "rounded bg-gray-100 px-1 py-0.5", children: ["/", col.urlPrefix] })] })), ' ', "\u2014 ", col.type] })] }) }), _jsxs("div", { className: "grid grid-cols-1 gap-3 md:grid-cols-3", children: [_jsx(Select, { label: "Default Schema.org type", value: override.defaultSchemaType ?? '', options: SCHEMA_TYPES, onChange: (v) => patchCollection(col.slug, 'defaultSchemaType', v || undefined), placeholderLabel: `default: ${staticC.defaultSchemaType ?? 'auto-detect'}` }), _jsx(Field, { label: "Archive path", placeholder: staticC.archivePath ?? '/blog', value: override.archivePath ?? '', onChange: (v) => patchCollection(col.slug, 'archivePath', v) }), _jsx(Select, { label: "Sitemap change frequency", value: override.sitemapChangeFreq ?? '', options: CHANGE_FREQS, onChange: (v) => patchCollection(col.slug, 'sitemapChangeFreq', v), placeholderLabel: `default: ${staticC.sitemapChangeFreq ?? 'weekly'}` }), _jsx(NumberField, { label: "Sitemap priority", value: override.sitemapPriority, placeholder: `default: ${staticC.sitemapPriority ?? (col.type === 'page' ? 0.8 : 0.6)}`, onChange: (v) => patchCollection(col.slug, 'sitemapPriority', v), min: 0, max: 1, step: 0.1 })] }), _jsxs("div", { className: "mt-3 flex flex-wrap gap-4", children: [_jsx(Toggle, { label: "Exclude from sitemap", checked: !!override.excludeFromSitemap, onChange: (v) => patchCollection(col.slug, 'excludeFromSitemap', v) }), _jsx(Toggle, { label: "Default: noindex", checked: !!override.defaultRobots?.noIndex, onChange: (v) => patchCollectionRobots(col.slug, 'noIndex', v) }), _jsx(Toggle, { label: "Default: nofollow", checked: !!override.defaultRobots?.noFollow, onChange: (v) => patchCollectionRobots(col.slug, 'noFollow', v) })] })] }, col.slug));
136
+ }), data?.collections.length === 0 && (_jsxs("div", { className: "p-4 text-sm text-gray-500", children: ["No collections configured in ", _jsx("code", { children: "actuate.config.ts" }), "."] }))] })] }), _jsx("div", { className: "flex justify-end", children: _jsxs("button", { onClick: handleSave, disabled: saving, className: "inline-flex items-center gap-1.5 rounded-md bg-blue-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-blue-700 disabled:opacity-50", children: [saving ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : _jsx(Save, { className: "h-4 w-4" }), "Save SEO defaults"] }) })] }));
137
+ }
138
+ function stripEmpty(obj) {
139
+ const out = {};
140
+ for (const [k, v] of Object.entries(obj)) {
141
+ if (v === undefined || v === null)
142
+ continue;
143
+ if (typeof v === 'string' && v.trim() === '')
144
+ continue;
145
+ if (typeof v === 'object' && !Array.isArray(v)) {
146
+ const nested = stripEmpty(v);
147
+ if (Object.keys(nested).length > 0)
148
+ out[k] = nested;
149
+ continue;
150
+ }
151
+ out[k] = v;
152
+ }
153
+ return out;
154
+ }
155
+ function Field({ label, value, placeholder, onChange, hint, }) {
156
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-gray-700", children: label }), _jsx("input", { type: "text", value: value, placeholder: placeholder, onChange: (e) => onChange(e.target.value), className: "w-full rounded-md border border-gray-300 px-2.5 py-1.5 text-sm text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" }), hint && _jsx("p", { className: "mt-1 text-[11px] text-gray-500", children: hint })] }));
157
+ }
158
+ function NumberField({ label, value, placeholder, onChange, min, max, step, hint, }) {
159
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-gray-700", children: label }), _jsx("input", { type: "number", value: value ?? '', placeholder: placeholder, min: min, max: max, step: step, onChange: (e) => {
160
+ const raw = e.target.value;
161
+ if (raw === '')
162
+ return onChange(undefined);
163
+ const n = Number(raw);
164
+ if (Number.isFinite(n))
165
+ onChange(n);
166
+ }, className: "w-full rounded-md border border-gray-300 px-2.5 py-1.5 text-sm text-gray-900 placeholder-gray-400 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none" }), hint && _jsx("p", { className: "mt-1 text-[11px] text-gray-500", children: hint })] }));
167
+ }
168
+ function Select({ label, value, options, onChange, placeholderLabel, hint, }) {
169
+ return (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-xs font-medium text-gray-700", children: label }), _jsx("select", { value: value, onChange: (e) => onChange(e.target.value), className: "w-full rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-sm text-gray-900 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:outline-none", children: options.map((opt) => (_jsx("option", { value: opt, children: opt === '' ? (placeholderLabel ?? '— use default —') : opt }, opt))) }), hint && _jsx("p", { className: "mt-1 text-[11px] text-gray-500", children: hint })] }));
170
+ }
171
+ function Toggle({ label, checked, onChange, hint, }) {
172
+ return (_jsxs("label", { className: "flex cursor-pointer items-center gap-2 text-sm text-gray-700", children: [_jsx("input", { type: "checkbox", checked: checked, onChange: (e) => onChange(e.target.checked), className: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500" }), _jsxs("span", { children: [label, hint && _jsxs("span", { className: "ml-1 text-[11px] text-gray-500", children: ["\u2014 ", hint] })] })] }));
173
+ }
174
+ //# sourceMappingURL=SEOConfigPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SEOConfigPanel.js","sourceRoot":"","sources":["../../src/components/SEOConfigPanel.tsx"],"names":[],"mappings":"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"}
@@ -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