@jhits/plugin-blog 0.0.19 → 0.0.20

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 (291) hide show
  1. package/dist/api/categories.d.ts.map +1 -1
  2. package/dist/api/categories.js +42 -38
  3. package/dist/api/handler.d.ts +1 -26
  4. package/dist/api/handler.d.ts.map +1 -1
  5. package/dist/api/handler.js +81 -490
  6. package/dist/api/router.d.ts +0 -5
  7. package/dist/api/router.d.ts.map +1 -1
  8. package/dist/api/router.js +8 -35
  9. package/dist/api/service.d.ts +80 -0
  10. package/dist/api/service.d.ts.map +1 -0
  11. package/dist/api/service.js +219 -0
  12. package/dist/hooks/useAutoSave.d.ts +10 -0
  13. package/dist/hooks/useAutoSave.d.ts.map +1 -0
  14. package/dist/hooks/useAutoSave.js +57 -0
  15. package/dist/hooks/useCategories.d.ts +1 -1
  16. package/dist/hooks/useCategories.d.ts.map +1 -1
  17. package/dist/hooks/useCategories.js +15 -46
  18. package/dist/index.d.ts +24 -31
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +44 -201
  21. package/dist/init.d.ts +20 -7
  22. package/dist/init.d.ts.map +1 -1
  23. package/dist/init.js +8 -7
  24. package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -1
  25. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -1
  26. package/dist/lib/layouts/blocks/ColumnsBlock.js +30 -113
  27. package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -1
  28. package/dist/lib/layouts/blocks/SectionBlock.js +9 -21
  29. package/dist/lib/layouts/index.d.ts +3 -3
  30. package/dist/lib/layouts/index.js +4 -4
  31. package/dist/lib/mappers/apiMapper.d.ts +10 -0
  32. package/dist/lib/mappers/apiMapper.d.ts.map +1 -1
  33. package/dist/lib/mappers/apiMapper.js +47 -32
  34. package/dist/lib/rich-text/RichTextEditor.d.ts +4 -2
  35. package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -1
  36. package/dist/lib/rich-text/RichTextEditor.js +12 -9
  37. package/dist/lib/utils/config-resolver.d.ts +28 -0
  38. package/dist/lib/utils/config-resolver.d.ts.map +1 -0
  39. package/dist/lib/utils/config-resolver.js +46 -0
  40. package/dist/lib/utils/tree.d.ts +29 -0
  41. package/dist/lib/utils/tree.d.ts.map +1 -0
  42. package/dist/lib/utils/tree.js +129 -0
  43. package/dist/state/EditorContext.d.ts +3 -25
  44. package/dist/state/EditorContext.d.ts.map +1 -1
  45. package/dist/state/EditorContext.js +124 -174
  46. package/dist/state/reducer.d.ts +1 -5
  47. package/dist/state/reducer.d.ts.map +1 -1
  48. package/dist/state/reducer.js +128 -521
  49. package/dist/state/types.d.ts +12 -1
  50. package/dist/state/types.d.ts.map +1 -1
  51. package/dist/types/block.d.ts +9 -0
  52. package/dist/types/block.d.ts.map +1 -1
  53. package/dist/types/post.d.ts +17 -1
  54. package/dist/types/post.d.ts.map +1 -1
  55. package/dist/views/CanvasEditor/BlockWrapper.d.ts +5 -6
  56. package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -1
  57. package/dist/views/CanvasEditor/BlockWrapper.js +56 -264
  58. package/dist/views/CanvasEditor/CanvasEditorView.d.ts +5 -3
  59. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
  60. package/dist/views/CanvasEditor/CanvasEditorView.js +55 -315
  61. package/dist/views/CanvasEditor/EditorBody.d.ts +6 -8
  62. package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -1
  63. package/dist/views/CanvasEditor/EditorBody.js +34 -482
  64. package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -1
  65. package/dist/views/CanvasEditor/EditorHeader.js +27 -63
  66. package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -1
  67. package/dist/views/CanvasEditor/LayoutContainer.js +49 -70
  68. package/dist/views/CanvasEditor/components/CustomBlockItem.js +1 -1
  69. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +15 -3
  70. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -1
  71. package/dist/views/CanvasEditor/components/EditorCanvas.js +40 -18
  72. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +5 -1
  73. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -1
  74. package/dist/views/CanvasEditor/components/EditorLibrary.js +11 -7
  75. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
  76. package/dist/views/CanvasEditor/components/EditorSidebar.js +32 -14
  77. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -6
  78. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -1
  79. package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +17 -128
  80. package/dist/views/CanvasEditor/components/JSONInspector.d.ts +9 -0
  81. package/dist/views/CanvasEditor/components/JSONInspector.d.ts.map +1 -0
  82. package/dist/views/CanvasEditor/components/JSONInspector.js +56 -0
  83. package/dist/views/CanvasEditor/components/LibraryItem.js +2 -2
  84. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -4
  85. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -1
  86. package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +6 -28
  87. package/dist/views/CanvasEditor/components/index.d.ts +2 -0
  88. package/dist/views/CanvasEditor/components/index.d.ts.map +1 -1
  89. package/dist/views/CanvasEditor/components/index.js +1 -0
  90. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -1
  91. package/dist/views/CanvasEditor/hooks/useHeroBlock.js +15 -18
  92. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +3 -0
  93. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -1
  94. package/dist/views/CanvasEditor/hooks/usePostLoader.js +12 -13
  95. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +0 -4
  96. package/dist/views/PostManager/EmptyState.d.ts +1 -1
  97. package/dist/views/PostManager/EmptyState.js +4 -4
  98. package/dist/views/PostManager/FilterDropdown.d.ts +21 -0
  99. package/dist/views/PostManager/FilterDropdown.d.ts.map +1 -0
  100. package/dist/views/PostManager/FilterDropdown.js +28 -0
  101. package/dist/views/PostManager/LanguageFlags.d.ts.map +1 -1
  102. package/dist/views/PostManager/LanguageFlags.js +4 -1
  103. package/dist/views/PostManager/PostCards.d.ts.map +1 -1
  104. package/dist/views/PostManager/PostCards.js +23 -40
  105. package/dist/views/PostManager/PostFilters.d.ts.map +1 -1
  106. package/dist/views/PostManager/PostFilters.js +34 -3
  107. package/dist/views/PostManager/PostManagerView.d.ts +1 -2
  108. package/dist/views/PostManager/PostManagerView.d.ts.map +1 -1
  109. package/dist/views/PostManager/PostManagerView.js +30 -96
  110. package/dist/views/PostManager/PostStats.d.ts.map +1 -1
  111. package/dist/views/PostManager/PostStats.js +10 -10
  112. package/dist/views/PostManager/PostTable.d.ts.map +1 -1
  113. package/dist/views/PostManager/PostTable.js +23 -40
  114. package/dist/views/Settings/SettingsView.d.ts +1 -1
  115. package/dist/views/Settings/SettingsView.d.ts.map +1 -1
  116. package/dist/views/Settings/SettingsView.js +12 -39
  117. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -1
  118. package/dist/views/SlugSEO/SlugSEOManagerView.js +2 -2
  119. package/package.json +42 -6
  120. package/src/api/categories.ts +48 -52
  121. package/src/api/handler.ts +87 -594
  122. package/src/api/router.ts +15 -65
  123. package/src/api/service.ts +241 -0
  124. package/src/hooks/useAutoSave.ts +64 -0
  125. package/src/hooks/useCategories.ts +19 -47
  126. package/src/index.tsx +79 -293
  127. package/src/init.tsx +24 -11
  128. package/src/lib/blocks/BlockRenderer.tsx +1 -0
  129. package/src/lib/layouts/blocks/ColumnsBlock.tsx +60 -173
  130. package/src/lib/layouts/blocks/SectionBlock.tsx +22 -26
  131. package/src/lib/layouts/index.ts +4 -4
  132. package/src/lib/mappers/apiMapper.ts +63 -32
  133. package/src/lib/rich-text/RichTextEditor.tsx +16 -9
  134. package/src/lib/utils/config-resolver.ts +64 -0
  135. package/src/lib/utils/tree.ts +150 -0
  136. package/src/state/EditorContext.tsx +153 -232
  137. package/src/state/reducer.ts +141 -606
  138. package/src/state/types.ts +14 -1
  139. package/src/types/block.ts +10 -0
  140. package/src/types/post.ts +19 -1
  141. package/src/views/CanvasEditor/BlockWrapper.tsx +130 -460
  142. package/src/views/CanvasEditor/CanvasEditorView.tsx +145 -420
  143. package/src/views/CanvasEditor/EditorBody.tsx +98 -610
  144. package/src/views/CanvasEditor/EditorHeader.tsx +176 -196
  145. package/src/views/CanvasEditor/LayoutContainer.tsx +74 -89
  146. package/src/views/CanvasEditor/components/CustomBlockItem.tsx +7 -8
  147. package/src/views/CanvasEditor/components/EditorCanvas.tsx +139 -84
  148. package/src/views/CanvasEditor/components/EditorLibrary.tsx +25 -10
  149. package/src/views/CanvasEditor/components/EditorSidebar.tsx +196 -127
  150. package/src/views/CanvasEditor/components/FeaturedMediaSection.tsx +78 -210
  151. package/src/views/CanvasEditor/components/JSONInspector.tsx +125 -0
  152. package/src/views/CanvasEditor/components/LibraryItem.tsx +5 -6
  153. package/src/views/CanvasEditor/components/PrivacySettingsSection.tsx +73 -124
  154. package/src/views/CanvasEditor/components/index.ts +2 -1
  155. package/src/views/CanvasEditor/hooks/useHeroBlock.ts +15 -18
  156. package/src/views/CanvasEditor/hooks/usePostLoader.ts +21 -13
  157. package/src/views/CanvasEditor/hooks/useUnsavedChanges.ts +4 -4
  158. package/src/views/PostManager/EmptyState.tsx +9 -10
  159. package/src/views/PostManager/FilterDropdown.tsx +95 -0
  160. package/src/views/PostManager/LanguageFlags.tsx +6 -2
  161. package/src/views/PostManager/PostCards.tsx +127 -133
  162. package/src/views/PostManager/PostFilters.tsx +73 -68
  163. package/src/views/PostManager/PostManagerView.tsx +132 -179
  164. package/src/views/PostManager/PostStats.tsx +21 -20
  165. package/src/views/PostManager/PostTable.tsx +137 -165
  166. package/src/views/Settings/SettingsView.tsx +64 -180
  167. package/src/views/SlugSEO/SlugSEOManagerView.tsx +59 -44
  168. package/src/hooks/index.d.ts +0 -8
  169. package/src/hooks/index.d.ts.map +0 -1
  170. package/src/hooks/useBlog.d.ts +0 -31
  171. package/src/hooks/useBlog.d.ts.map +0 -1
  172. package/src/hooks/useBlogs.d.ts +0 -39
  173. package/src/hooks/useBlogs.d.ts.map +0 -1
  174. package/src/hooks/useCategories.d.ts +0 -9
  175. package/src/hooks/useCategories.d.ts.map +0 -1
  176. package/src/lib/blocks/BlockRenderer.d.ts +0 -54
  177. package/src/lib/blocks/BlockRenderer.d.ts.map +0 -1
  178. package/src/lib/config-storage.d.ts +0 -30
  179. package/src/lib/config-storage.d.ts.map +0 -1
  180. package/src/lib/layouts/blocks/ColumnsBlock.d.ts +0 -25
  181. package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +0 -1
  182. package/src/lib/layouts/blocks/SectionBlock.d.ts +0 -25
  183. package/src/lib/layouts/blocks/SectionBlock.d.ts.map +0 -1
  184. package/src/lib/layouts/index.d.ts +0 -23
  185. package/src/lib/layouts/index.d.ts.map +0 -1
  186. package/src/lib/layouts/registerLayoutBlocks.d.ts +0 -9
  187. package/src/lib/layouts/registerLayoutBlocks.d.ts.map +0 -1
  188. package/src/lib/mappers/apiMapper.d.ts +0 -66
  189. package/src/lib/mappers/apiMapper.d.ts.map +0 -1
  190. package/src/lib/rich-text/RichTextEditor.d.ts +0 -45
  191. package/src/lib/rich-text/RichTextEditor.d.ts.map +0 -1
  192. package/src/lib/rich-text/RichTextPreview.d.ts +0 -16
  193. package/src/lib/rich-text/RichTextPreview.d.ts.map +0 -1
  194. package/src/lib/rich-text/index.d.ts +0 -9
  195. package/src/lib/rich-text/index.d.ts.map +0 -1
  196. package/src/lib/utils/blockHelpers.d.ts +0 -23
  197. package/src/lib/utils/blockHelpers.d.ts.map +0 -1
  198. package/src/lib/utils/configValidation.d.ts +0 -23
  199. package/src/lib/utils/configValidation.d.ts.map +0 -1
  200. package/src/registry/BlockRegistry.d.ts +0 -62
  201. package/src/registry/BlockRegistry.d.ts.map +0 -1
  202. package/src/registry/index.d.ts +0 -6
  203. package/src/registry/index.d.ts.map +0 -1
  204. package/src/state/EditorContext.d.ts +0 -45
  205. package/src/state/EditorContext.d.ts.map +0 -1
  206. package/src/state/index.d.ts +0 -7
  207. package/src/state/index.d.ts.map +0 -1
  208. package/src/state/reducer.d.ts +0 -11
  209. package/src/state/reducer.d.ts.map +0 -1
  210. package/src/state/types.d.ts +0 -162
  211. package/src/state/types.d.ts.map +0 -1
  212. package/src/types/block.d.ts +0 -221
  213. package/src/types/block.d.ts.map +0 -1
  214. package/src/types/index.d.ts +0 -8
  215. package/src/types/index.d.ts.map +0 -1
  216. package/src/types/post.d.ts +0 -136
  217. package/src/types/post.d.ts.map +0 -1
  218. package/src/utils/client.d.ts +0 -48
  219. package/src/utils/client.d.ts.map +0 -1
  220. package/src/views/CanvasEditor/BlockWrapper.d.ts +0 -16
  221. package/src/views/CanvasEditor/BlockWrapper.d.ts.map +0 -1
  222. package/src/views/CanvasEditor/CanvasEditorView.d.ts +0 -14
  223. package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +0 -1
  224. package/src/views/CanvasEditor/EditorBody.d.ts +0 -22
  225. package/src/views/CanvasEditor/EditorBody.d.ts.map +0 -1
  226. package/src/views/CanvasEditor/EditorHeader.d.ts +0 -18
  227. package/src/views/CanvasEditor/EditorHeader.d.ts.map +0 -1
  228. package/src/views/CanvasEditor/LayoutContainer.d.ts +0 -17
  229. package/src/views/CanvasEditor/LayoutContainer.d.ts.map +0 -1
  230. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +0 -13
  231. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +0 -1
  232. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +0 -14
  233. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +0 -1
  234. package/src/views/CanvasEditor/components/EditorCanvas.d.ts +0 -29
  235. package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +0 -1
  236. package/src/views/CanvasEditor/components/EditorLibrary.d.ts +0 -7
  237. package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +0 -1
  238. package/src/views/CanvasEditor/components/EditorSidebar.d.ts +0 -13
  239. package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +0 -1
  240. package/src/views/CanvasEditor/components/ErrorBanner.d.ts +0 -6
  241. package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +0 -1
  242. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -25
  243. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +0 -1
  244. package/src/views/CanvasEditor/components/LibraryItem.d.ts +0 -14
  245. package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +0 -1
  246. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -15
  247. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +0 -1
  248. package/src/views/CanvasEditor/components/index.d.ts +0 -21
  249. package/src/views/CanvasEditor/components/index.d.ts.map +0 -1
  250. package/src/views/CanvasEditor/hooks/index.d.ts +0 -10
  251. package/src/views/CanvasEditor/hooks/index.d.ts.map +0 -1
  252. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +0 -8
  253. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +0 -1
  254. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +0 -3
  255. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  256. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +0 -5
  257. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +0 -1
  258. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +0 -2
  259. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +0 -1
  260. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +0 -25
  261. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +0 -1
  262. package/src/views/CanvasEditor/index.d.ts +0 -16
  263. package/src/views/CanvasEditor/index.d.ts.map +0 -1
  264. package/src/views/PostManager/EmptyState.d.ts +0 -10
  265. package/src/views/PostManager/EmptyState.d.ts.map +0 -1
  266. package/src/views/PostManager/PostActionsMenu.d.ts +0 -12
  267. package/src/views/PostManager/PostActionsMenu.d.ts.map +0 -1
  268. package/src/views/PostManager/PostCards.d.ts +0 -15
  269. package/src/views/PostManager/PostCards.d.ts.map +0 -1
  270. package/src/views/PostManager/PostFilters.d.ts +0 -16
  271. package/src/views/PostManager/PostFilters.d.ts.map +0 -1
  272. package/src/views/PostManager/PostManagerView.d.ts +0 -11
  273. package/src/views/PostManager/PostManagerView.d.ts.map +0 -1
  274. package/src/views/PostManager/PostStats.d.ts +0 -11
  275. package/src/views/PostManager/PostStats.d.ts.map +0 -1
  276. package/src/views/PostManager/PostTable.d.ts +0 -15
  277. package/src/views/PostManager/PostTable.d.ts.map +0 -1
  278. package/src/views/PostManager/index.d.ts +0 -12
  279. package/src/views/PostManager/index.d.ts.map +0 -1
  280. package/src/views/Preview/PreviewBridgeView.d.ts +0 -12
  281. package/src/views/Preview/PreviewBridgeView.d.ts.map +0 -1
  282. package/src/views/Preview/index.d.ts +0 -6
  283. package/src/views/Preview/index.d.ts.map +0 -1
  284. package/src/views/Settings/SettingsView.d.ts +0 -10
  285. package/src/views/Settings/SettingsView.d.ts.map +0 -1
  286. package/src/views/Settings/index.d.ts +0 -6
  287. package/src/views/Settings/index.d.ts.map +0 -1
  288. package/src/views/SlugSEO/SlugSEOManagerView.d.ts +0 -12
  289. package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +0 -1
  290. package/src/views/SlugSEO/index.d.ts +0 -6
  291. package/src/views/SlugSEO/index.d.ts.map +0 -1
@@ -1,18 +1,16 @@
1
1
  /**
2
2
  * Post Manager View
3
- * Production-ready listing page for managing blog posts
4
- * Follows dashboard earth-tone design system
3
+ * Natural scroll layout with sticky header synchronization
5
4
  */
6
5
  'use client';
7
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
7
  import React, { useState, useEffect } from 'react';
9
- import { Plus, List, Grid3x3 } from 'lucide-react';
8
+ import { Plus, List, Grid3x3, Settings, Loader2, Zap } from 'lucide-react';
10
9
  import { PostStats } from './PostStats';
11
10
  import { PostFilters } from './PostFilters';
12
11
  import { PostTable } from './PostTable';
13
12
  import { PostCards } from './PostCards';
14
13
  import { EmptyState } from './EmptyState';
15
- import { apiToBlogPost } from '../../lib/mappers/apiMapper';
16
14
  const STORAGE_KEY_PREFIX = 'blog-view-mode';
17
15
  export function PostManagerView({ siteId, locale }) {
18
16
  const [posts, setPosts] = useState([]);
@@ -22,7 +20,6 @@ export function PostManagerView({ siteId, locale }) {
22
20
  const [statusFilter, setStatusFilter] = useState('all');
23
21
  const [categoryFilter, setCategoryFilter] = useState('all');
24
22
  const [currentLanguage, setCurrentLanguage] = useState(locale || 'nl');
25
- // Load view mode preference from localStorage
26
23
  const getStoredViewMode = () => {
27
24
  if (typeof window === 'undefined')
28
25
  return 'list';
@@ -30,13 +27,11 @@ export function PostManagerView({ siteId, locale }) {
30
27
  return (stored === 'list' || stored === 'cards') ? stored : 'list';
31
28
  };
32
29
  const [viewMode, setViewMode] = useState(getStoredViewMode);
33
- // Save view mode preference to localStorage when it changes
34
30
  useEffect(() => {
35
31
  if (typeof window !== 'undefined') {
36
32
  localStorage.setItem(`${STORAGE_KEY_PREFIX}-${siteId}`, viewMode);
37
33
  }
38
34
  }, [viewMode, siteId]);
39
- // Fetch posts from API
40
35
  useEffect(() => {
41
36
  const fetchPosts = async () => {
42
37
  try {
@@ -44,39 +39,20 @@ export function PostManagerView({ siteId, locale }) {
44
39
  const response = await fetch(`/api/plugin-blog?admin=true&language=${currentLanguage}`);
45
40
  const data = await response.json();
46
41
  if (data.blogs && Array.isArray(data.blogs)) {
47
- // Convert API format to PostListItem format
48
42
  const postListItems = data.blogs.map((doc) => {
49
- const blogPost = apiToBlogPost(doc);
50
- // Use semantic ID (id) - plugin-images handles resolution
51
- // The id is the semantic ID (e.g., "blog-featured-{slug}") which plugin-images resolves
52
- const featuredImageId = blogPost.metadata.featuredImage?.id;
53
- // Extract category from metadata or hero block
54
- let category = undefined;
55
- if (blogPost.metadata.categories && blogPost.metadata.categories.length > 0) {
56
- category = blogPost.metadata.categories[0];
57
- }
58
- else {
59
- // Check hero block for category
60
- const heroBlock = blogPost.blocks.find(block => block.type === 'hero');
61
- if (heroBlock && heroBlock.data && typeof heroBlock.data === 'object') {
62
- const heroCategory = heroBlock.data.category;
63
- if (heroCategory && typeof heroCategory === 'string' && heroCategory.trim()) {
64
- category = heroCategory.trim();
65
- }
66
- }
67
- }
68
43
  return {
69
- id: blogPost.id,
70
- title: blogPost.title,
71
- slug: blogPost.slug,
72
- status: blogPost.publication.status,
73
- date: blogPost.publication.date,
74
- excerpt: blogPost.metadata.excerpt,
75
- featuredImage: featuredImageId,
76
- authorId: blogPost.publication.authorId,
77
- updatedAt: blogPost.updatedAt,
78
- category: category,
79
- lang: blogPost.metadata.lang,
44
+ id: doc.id,
45
+ title: doc.title,
46
+ slug: doc.slug,
47
+ status: doc.status,
48
+ date: doc.publication?.date,
49
+ excerpt: doc.summary,
50
+ featuredImage: doc.image?.id || doc.image?.src,
51
+ authorId: doc.authorId,
52
+ author: doc.author,
53
+ updatedAt: doc.updatedAt || doc.publication?.date || doc.date || new Date().toISOString(),
54
+ category: doc.categoryTags?.category,
55
+ lang: doc.lang,
80
56
  availableLanguages: doc.availableLanguages,
81
57
  languages: doc.languages,
82
58
  };
@@ -94,7 +70,6 @@ export function PostManagerView({ siteId, locale }) {
94
70
  };
95
71
  fetchPosts();
96
72
  }, [currentLanguage]);
97
- // Extract unique categories from posts
98
73
  const categories = React.useMemo(() => {
99
74
  const categorySet = new Set();
100
75
  posts.forEach(post => {
@@ -104,7 +79,6 @@ export function PostManagerView({ siteId, locale }) {
104
79
  });
105
80
  return Array.from(categorySet).sort();
106
81
  }, [posts]);
107
- // Extract unique languages from all posts
108
82
  const availableLanguages = React.useMemo(() => {
109
83
  const langSet = new Set();
110
84
  posts.forEach(post => {
@@ -114,14 +88,12 @@ export function PostManagerView({ siteId, locale }) {
114
88
  if (post.lang)
115
89
  langSet.add(post.lang);
116
90
  });
117
- // Always include the current locale/language to ensure it's selectable
118
91
  if (locale)
119
92
  langSet.add(locale);
120
93
  if (currentLanguage)
121
94
  langSet.add(currentLanguage);
122
95
  return Array.from(langSet).sort();
123
96
  }, [posts, locale, currentLanguage]);
124
- // Filter posts
125
97
  const filteredPosts = React.useMemo(() => {
126
98
  return posts.filter((post) => {
127
99
  const matchesSearch = search === '' ||
@@ -133,68 +105,30 @@ export function PostManagerView({ siteId, locale }) {
133
105
  return matchesSearch && matchesStatus && matchesCategory;
134
106
  });
135
107
  }, [posts, search, statusFilter, categoryFilter]);
136
- // Action handlers
137
- const handleCreatePost = () => {
138
- // Navigate to editor route - the plugin router will handle this
139
- // The route 'new' maps to the editor view
140
- window.location.href = '/dashboard/blog/new';
141
- };
108
+ const handleCreatePost = () => { window.location.href = '/dashboard/blog/new'; };
142
109
  const handleEdit = (postId) => {
143
- // Find the post to get its slug
144
110
  const post = posts.find(p => p.id === postId);
145
- if (post) {
146
- // Navigate to editor with slug (API uses slug, not ID)
111
+ if (post)
147
112
  window.location.href = `/dashboard/blog/editor/${post.slug}`;
148
- }
149
- };
150
- const handlePreview = (postId) => {
151
- // Open preview in new tab
152
- window.open(`/dashboard/blog/preview/${postId}`, '_blank');
153
- };
154
- const handleDuplicate = (postId) => {
155
- // TODO: Implement duplicate functionality
156
- const post = posts.find((p) => p.id === postId);
157
- if (post) {
158
- const duplicated = {
159
- ...post,
160
- id: `duplicate-${Date.now()}`,
161
- title: `${post.title} (Copy)`,
162
- slug: `${post.slug}-copy-${Date.now()}`,
163
- status: 'draft',
164
- updatedAt: new Date().toISOString(),
165
- };
166
- setPosts((prev) => [...prev, duplicated]);
167
- }
168
113
  };
114
+ const handlePreview = (postId) => { window.open(`/dashboard/blog/preview/${postId}`, '_blank'); };
115
+ const handleDuplicate = (postId) => { };
169
116
  const handleDelete = async (postId) => {
170
- if (confirm('Are you sure you want to delete this post?')) {
171
- try {
172
- const post = posts.find(p => p.id === postId);
173
- if (post) {
174
- const response = await fetch(`/api/plugin-blog/${post.slug}`, {
175
- method: 'DELETE',
176
- });
177
- if (response.ok) {
178
- // Remove from local state
179
- setPosts((prev) => prev.filter((p) => p.id !== postId));
180
- setTotalPosts(prev => prev - 1);
181
- }
182
- else {
183
- const error = await response.json();
184
- alert(error.error || 'Failed to delete post');
185
- }
117
+ if (confirm('Are you sure?')) {
118
+ const post = posts.find(p => p.id === postId);
119
+ if (post) {
120
+ const res = await fetch(`/api/plugin-blog/${post.slug}`, { method: 'DELETE' });
121
+ if (res.ok) {
122
+ setPosts((prev) => prev.filter((p) => p.id !== postId));
123
+ setTotalPosts(prev => prev - 1);
186
124
  }
187
125
  }
188
- catch (error) {
189
- console.error('Failed to delete post:', error);
190
- alert('Failed to delete post');
191
- }
192
126
  }
193
127
  };
194
128
  const hasActiveFilters = search !== '' || statusFilter !== 'all' || categoryFilter !== 'all';
195
- return (_jsxs("div", { className: "h-full w-full rounded-[2.5rem] bg-white dark:bg-neutral-900 p-8 overflow-y-auto", children: [_jsxs("div", { className: "flex flex-col md:flex-row md:items-center justify-between gap-6 mb-8", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-3xl font-black text-neutral-950 dark:text-white uppercase tracking-tighter mb-2", children: "Blog Posts" }), _jsx("p", { className: "text-sm text-neutral-500 dark:text-neutral-400", children: "Manage your blog posts, drafts, and published content" })] }), _jsxs("button", { onClick: handleCreatePost, className: "inline-flex items-center gap-2 px-6 py-3 bg-primary text-white rounded-full text-[10px] font-black uppercase tracking-widest hover:bg-primary/90 transition-all shadow-lg shadow-primary/20", children: [_jsx(Plus, { size: 16 }), "New Post"] })] }), _jsx(PostStats, { total: totalPosts, posts: posts }), _jsxs("div", { className: "flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-6", children: [_jsx(PostFilters, { search: search, onSearchChange: setSearch, statusFilter: statusFilter, onStatusFilterChange: setStatusFilter, categoryFilter: categoryFilter, onCategoryFilterChange: setCategoryFilter, categories: categories, language: currentLanguage, onLanguageChange: setCurrentLanguage, availableLanguages: availableLanguages }), _jsxs("div", { className: "flex items-center gap-2 bg-neutral-100 dark:bg-neutral-800/50 rounded-full p-1 border border-neutral-300 dark:border-neutral-700", children: [_jsx("button", { onClick: () => setViewMode('list'), className: `p-2 rounded-full transition-all ${viewMode === 'list'
196
- ? 'bg-white dark:bg-neutral-900 text-primary shadow-sm'
197
- : 'text-neutral-500 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'}`, title: "List View", children: _jsx(List, { size: 18 }) }), _jsx("button", { onClick: () => setViewMode('cards'), className: `p-2 rounded-full transition-all ${viewMode === 'cards'
198
- ? 'bg-white dark:bg-neutral-900 text-primary shadow-sm'
199
- : 'text-neutral-500 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'}`, title: "Card View", children: _jsx(Grid3x3, { size: 18 }) })] })] }), loading ? (_jsx("div", { className: "flex items-center justify-center py-20", children: _jsx("div", { className: "w-8 h-8 border-4 border-primary/20 border-t-primary rounded-full animate-spin" }) })) : filteredPosts.length === 0 ? (_jsx(EmptyState, { hasFilters: hasActiveFilters, onCreatePost: handleCreatePost })) : viewMode === 'list' ? (_jsx(PostTable, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete })) : (_jsx(PostCards, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete }))] }));
129
+ return (_jsxs("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent", children: [_jsxs("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-8 px-2", children: [_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/15 border border-primary/30 text-primary text-[10px] font-bold uppercase tracking-wider shadow-sm", children: [_jsx(Zap, { size: 12, className: "fill-primary animate-pulse" }), _jsx("span", { children: "Editorial Content Control" })] }), _jsxs("div", { children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Blog ", _jsx("span", { className: "text-primary", children: "&" }), " Articles"] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium max-w-md leading-relaxed opacity-80", children: "Create and manage your digital publications and stories across the ecosystem." })] })] }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("button", { onClick: () => window.location.href = '/dashboard/blog/settings', className: "p-3.5 bg-dashboard-card/50 border border-dashboard-border/40 text-dashboard-text-secondary rounded-2xl hover:text-primary hover:border-primary/30 transition-all active:scale-95 shadow-sm", title: "Blog Settings", children: _jsx(Settings, { size: 18 }) }), _jsxs("button", { onClick: handleCreatePost, className: "group relative flex items-center gap-3 px-7 py-3.5 bg-primary text-white rounded-2xl text-[10px] font-bold uppercase tracking-widest overflow-hidden transition-all hover:scale-[1.02] active:scale-95 shadow-lg shadow-primary/20", children: [_jsx(Plus, { size: 18, className: "relative z-10" }), _jsx("span", { className: "relative z-10", children: "Add New Post" })] })] })] }), _jsx("div", { className: "px-2", children: _jsx(PostStats, { total: totalPosts, posts: posts }) }), _jsx("div", { className: "sticky top-[-40px] lg:top-[-40px] z-40 bg-dashboard-bg/40 backdrop-blur-xl border-y border-dashboard-border/40 py-4 px-2 ml-[-8px] mr-[-8px]", children: _jsxs("div", { className: "flex flex-col lg:flex-row items-center gap-4", children: [_jsx(PostFilters, { search: search, onSearchChange: setSearch, statusFilter: statusFilter, onStatusFilterChange: setStatusFilter, categoryFilter: categoryFilter, onCategoryFilterChange: setCategoryFilter, categories: categories, language: currentLanguage, onLanguageChange: setCurrentLanguage, availableLanguages: availableLanguages }), _jsxs("div", { className: "flex items-center gap-1.5 p-1.5 bg-dashboard-card/50 rounded-xl border border-dashboard-border/40", children: [_jsx("button", { onClick: () => setViewMode('list'), className: `p-2.5 rounded-lg transition-all ${viewMode === 'list'
130
+ ? 'bg-primary text-white shadow-lg shadow-primary/20'
131
+ : 'text-dashboard-text-secondary hover:text-primary hover:bg-primary/5'}`, title: "List View", children: _jsx(List, { size: 18 }) }), _jsx("button", { onClick: () => setViewMode('cards'), className: `p-2.5 rounded-lg transition-all ${viewMode === 'cards'
132
+ ? 'bg-primary text-white shadow-lg shadow-primary/20'
133
+ : 'text-dashboard-text-secondary hover:text-primary hover:bg-primary/5'}`, title: "Card View", children: _jsx(Grid3x3, { size: 18 }) })] })] }) }), _jsx("div", { className: "px-2 min-h-[400px] pb-32", children: loading ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-32 gap-4", children: [_jsx(Loader2, { className: "animate-spin text-primary opacity-40", size: 40 }), _jsx("p", { className: "text-[10px] font-bold text-primary uppercase tracking-widest animate-pulse", children: "Loading Publications" })] })) : filteredPosts.length === 0 ? (_jsx(EmptyState, { hasFilters: hasActiveFilters, onCreatePost: handleCreatePost })) : viewMode === 'list' ? (_jsx(PostTable, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete })) : (_jsx(PostCards, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete })) })] }));
200
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PostStats.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostStats.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,cAAc,2CA+DzD"}
1
+ {"version":3,"file":"PostStats.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostStats.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,cAAc,2CAgEzD"}
@@ -14,33 +14,33 @@ export function PostStats({ total, posts }) {
14
14
  label: 'Total Posts',
15
15
  value: total,
16
16
  icon: FileText,
17
- color: 'text-neutral-600 dark:text-neutral-400',
18
- bgColor: 'bg-neutral-100 dark:bg-neutral-800',
17
+ color: 'text-primary',
18
+ accent: 'bg-primary',
19
19
  },
20
20
  {
21
21
  label: 'Published',
22
22
  value: published,
23
23
  icon: CheckCircle2,
24
- color: 'text-green-600 dark:text-green-400',
25
- bgColor: 'bg-green-500/10 dark:bg-green-500/20',
24
+ color: 'text-emerald-500',
25
+ accent: 'bg-emerald-500',
26
26
  },
27
27
  {
28
28
  label: 'Drafts',
29
29
  value: drafts,
30
30
  icon: Clock,
31
- color: 'text-amber-600 dark:text-amber-400',
32
- bgColor: 'bg-amber-500/10 dark:bg-amber-500/20',
31
+ color: 'text-amber-500',
32
+ accent: 'bg-amber-500',
33
33
  },
34
34
  {
35
35
  label: 'Scheduled',
36
36
  value: scheduled,
37
37
  icon: Archive,
38
- color: 'text-blue-600 dark:text-blue-400',
39
- bgColor: 'bg-blue-500/10 dark:bg-blue-500/20',
38
+ color: 'text-blue-500',
39
+ accent: 'bg-blue-500',
40
40
  },
41
41
  ];
42
- return (_jsx("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-6", children: stats.map((stat) => {
42
+ return (_jsx("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-5", children: stats.map((stat) => {
43
43
  const Icon = stat.icon;
44
- return (_jsx("div", { className: `p-4 rounded-2xl border border-neutral-300 dark:border-neutral-700 ${stat.bgColor}`, children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: `p-2 rounded-xl ${stat.bgColor}`, children: _jsx(Icon, { className: `size-5 ${stat.color}` }) }), _jsxs("div", { children: [_jsx("p", { className: "text-2xl font-black text-neutral-950 dark:text-white", children: stat.value }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-400 uppercase tracking-wider", children: stat.label })] })] }) }, stat.label));
44
+ return (_jsxs("div", { className: "bg-dashboard-card/50 border border-dashboard-border/40 p-5 rounded-2xl relative overflow-hidden group transition-all duration-500", children: [_jsx("div", { className: `absolute top-0 right-0 p-4 opacity-5 group-hover:scale-105 transition-all duration-700 ${stat.color}`, children: _jsx(Icon, { size: 80 }) }), _jsxs("div", { className: "relative z-10", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("div", { className: `size-1.5 rounded-full ${stat.accent} animate-pulse shadow-[0_0_8px_rgba(var(--color-primary),0.5)]` }), _jsx("label", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest block opacity-80", children: stat.label })] }), _jsx("p", { className: `text-3xl font-bold tracking-tight ${stat.color}`, children: stat.value })] })] }, stat.label));
45
45
  }) }));
46
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PostTable.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostTable.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAK5D,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AA4BD,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,WAAW,EACX,QAAQ,GACX,EAAE,cAAc,2CAsLhB"}
1
+ {"version":3,"file":"PostTable.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostTable.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAK5D,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AA4BD,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,WAAW,EACX,QAAQ,GACX,EAAE,cAAc,2CA2JhB"}
@@ -4,26 +4,25 @@
4
4
  */
5
5
  'use client';
6
6
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
- import { useState, useEffect } from 'react';
8
- import { Calendar, User, UserCheck } from 'lucide-react';
9
- import { Image } from '@jhits/plugin-images';
7
+ import { FileText, Tag } from 'lucide-react';
8
+ import { Image as PluginImage } from '@jhits/plugin-images';
10
9
  import { PostActionsMenu } from './PostActionsMenu';
11
10
  import { LanguageFlags } from './LanguageFlags';
12
11
  import { useSession } from 'next-auth/react';
13
12
  function getStatusBadgeColor(status) {
14
13
  switch (status) {
15
14
  case 'published':
16
- return 'bg-green-500/10 text-green-700 dark:text-green-400 border-green-500/20';
15
+ return 'bg-emerald-500 text-white border-emerald-400 shadow-sm';
17
16
  case 'draft':
18
- return 'bg-amber-500/10 text-amber-700 dark:text-amber-400 border-amber-500/20';
17
+ return 'bg-amber-500 text-white border-amber-400 shadow-sm';
19
18
  case 'scheduled':
20
- return 'bg-blue-500/10 text-blue-700 dark:text-blue-400 border-blue-500/20';
19
+ return 'bg-blue-500 text-white border-blue-400 shadow-sm';
21
20
  case 'archived':
22
- return 'bg-neutral-500/10 text-neutral-700 dark:text-neutral-400 border-neutral-500/20';
21
+ return 'bg-neutral-500 text-white border-neutral-400';
23
22
  case 'not-translated':
24
- return 'bg-red-500/10 text-red-700 dark:text-red-400 border-red-500/20 italic';
23
+ return 'bg-red-500/10 text-red-500 border-red-500/20 italic';
25
24
  default:
26
- return 'bg-neutral-500/10 text-neutral-700 dark:text-neutral-400 border-neutral-500/20';
25
+ return 'bg-neutral-500/10 text-neutral-500 border-neutral-500/20';
27
26
  }
28
27
  }
29
28
  function formatDate(dateString, locale) {
@@ -38,43 +37,27 @@ function formatDate(dateString, locale) {
38
37
  export function PostTable({ posts, locale, onEdit, onPreview, onDuplicate, onDelete, }) {
39
38
  const { data: session, status: sessionStatus } = useSession();
40
39
  const currentUserId = session?.user?.id;
41
- const [userMap, setUserMap] = useState({});
42
40
  // Helper function to check if user is the owner
43
41
  const isPostOwner = (post) => {
44
42
  if (sessionStatus === 'loading')
45
- return false; // Don't show actions while loading
43
+ return false;
46
44
  if (!currentUserId || !post.authorId)
47
45
  return false;
48
- // Convert both to strings for comparison to handle ObjectId vs string
49
46
  return String(currentUserId) === String(post.authorId);
50
47
  };
51
- // Fetch users to map IDs to names
52
- useEffect(() => {
53
- const fetchUsers = async () => {
54
- try {
55
- const response = await fetch('/api/users');
56
- const users = await response.json();
57
- if (Array.isArray(users)) {
58
- const map = {};
59
- users.forEach((user) => {
60
- const id = user._id?.toString();
61
- if (id) {
62
- map[id] = user.name || user.email || 'Unknown';
63
- }
64
- });
65
- setUserMap(map);
66
- }
67
- }
68
- catch (error) {
69
- console.error('Failed to fetch users:', error);
70
- }
71
- };
72
- fetchUsers();
73
- }, []);
74
- const getAuthorName = (authorId) => {
75
- if (!authorId)
76
- return 'Unknown';
77
- return userMap[authorId] || authorId;
48
+ const getAuthorData = (post) => {
49
+ if (post.author) {
50
+ return {
51
+ name: post.author.name || 'Unknown Author',
52
+ image: post.author.image
53
+ };
54
+ }
55
+ return { name: 'Unknown Author' };
78
56
  };
79
- return (_jsx("div", { className: "bg-neutral-100 dark:bg-neutral-800/50 rounded-[2.5rem] border border-neutral-300 dark:border-neutral-700 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-neutral-200 dark:bg-neutral-900/50 border-b border-neutral-300 dark:border-neutral-700", children: _jsxs("tr", { children: [_jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Post" }), _jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Author" }), _jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Category" }), _jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Languages" }), _jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Status" }), _jsx("th", { className: "px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Last Modified" }), _jsx("th", { className: "px-6 py-4 text-right text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-neutral-300 dark:divide-neutral-700", children: posts.map((post) => (_jsxs("tr", { className: "hover:bg-white dark:hover:bg-neutral-900/50 transition-colors cursor-pointer", children: [_jsx("td", { className: "px-6 py-4", children: _jsxs("div", { className: "flex items-center gap-4", children: [post.featuredImage ? (_jsx("div", { className: "w-16 h-16 rounded-xl bg-neutral-200 dark:bg-neutral-700 overflow-hidden flex-shrink-0 relative", children: _jsx(Image, { id: post.featuredImage, alt: post.title, fill: true, editable: false, className: "w-full h-full object-cover" }) })) : (_jsx("div", { className: "w-16 h-16 rounded-xl bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center flex-shrink-0", children: _jsx("span", { className: "text-xs text-neutral-400", children: "No Image" }) })), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("button", { onClick: () => onEdit(post.id), className: "text-left w-full hover:cursor-pointer p-0 m-0 border-0 bg-transparent", children: _jsx("h3", { className: "font-bold hover:underline text-neutral-950 dark:text-white mb-1 line-clamp-1 text-left", children: post.title.trim() }) }), _jsxs("p", { className: "text-xs text-neutral-500 dark:text-neutral-400 font-mono text-left", children: ["/", post.slug] })] })] }) }), _jsx("td", { className: "px-6 py-4", children: _jsxs("div", { className: "flex items-center gap-2", children: [isPostOwner(post) ? (_jsx(UserCheck, { size: 14, className: "text-primary" })) : (_jsx(User, { size: 14, className: "text-neutral-400" })), _jsxs("span", { className: `text-sm ${isPostOwner(post) ? 'text-primary font-semibold' : 'text-neutral-600 dark:text-neutral-400'}`, children: [getAuthorName(post.authorId), isPostOwner(post) && (_jsx("span", { className: "ml-2 text-xs text-primary/70", children: "(Jij)" }))] })] }) }), _jsx("td", { className: "px-6 py-4", children: _jsx("span", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: post.category || 'Uncategorized' }) }), _jsx("td", { className: "px-6 py-4", children: _jsx(LanguageFlags, { post: post }) }), _jsx("td", { className: "px-6 py-4", children: _jsx("span", { className: `inline-flex items-center px-3 py-1 rounded-full text-[10px] font-black uppercase tracking-wider border ${getStatusBadgeColor(post.status)}`, children: post.status }) }), _jsx("td", { className: "px-6 py-4", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Calendar, { size: 14, className: "text-neutral-400" }), _jsx("span", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: formatDate(post.updatedAt, locale) })] }) }), _jsx("td", { className: "px-6 py-4", children: isPostOwner(post) ? (_jsx("div", { className: "flex items-center justify-end", children: _jsx(PostActionsMenu, { onEdit: () => onEdit(post.id), onPreview: () => onPreview(post.id), onDuplicate: () => onDuplicate(post.id), onDelete: () => onDelete(post.id) }) })) : (_jsx("div", { className: "flex items-center justify-end text-neutral-400 text-xs", children: "Alleen auteur" })) })] }, post.id))) })] }) }) }));
57
+ return (_jsx("div", { className: "bg-dashboard-card/40 rounded-[2rem] overflow-hidden border border-dashboard-border/40 shadow-sm", children: _jsx("div", { className: "overflow-x-auto custom-scrollbar", children: _jsxs("table", { className: "w-full text-left border-collapse min-w-[1000px] lg:min-w-0", children: [_jsx("thead", { children: _jsxs("tr", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest border-b border-dashboard-border/40 bg-dashboard-bg/20", children: [_jsx("th", { className: "px-8 py-5", children: "Publication" }), _jsx("th", { className: "px-8 py-5 hidden lg:table-cell", children: "Author" }), _jsx("th", { className: "px-8 py-5 hidden xl:table-cell", children: "Category" }), _jsx("th", { className: "px-8 py-5", children: "Editions" }), _jsx("th", { className: "px-8 py-5", children: "Status" }), _jsx("th", { className: "px-8 py-5 hidden md:table-cell", children: "Modified" }), _jsx("th", { className: "px-8 py-5 text-right", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-dashboard-border/30", children: posts.map((post) => {
58
+ const owner = isPostOwner(post);
59
+ const author = getAuthorData(post);
60
+ const initials = author.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
61
+ return (_jsxs("tr", { className: "group hover:bg-primary/[0.03] transition-colors", children: [_jsx("td", { className: "px-8 py-4", children: _jsxs("div", { className: "flex items-center gap-4", children: [post.featuredImage ? (_jsx("div", { className: `size-12 relative bg-dashboard-bg/50 rounded-xl overflow-hidden border transition-all shrink-0 ${owner ? 'border-primary/30' : 'border-dashboard-border/60'}`, children: _jsx(PluginImage, { id: post.featuredImage, alt: post.title, fill: true, editable: false, className: "object-cover" }) })) : (_jsx("div", { className: "size-12 rounded-xl bg-dashboard-bg/50 flex items-center justify-center border border-dashboard-border/60 opacity-20 shrink-0", children: _jsx(FileText, { size: 18 }) })), _jsxs("div", { className: "min-w-0", children: [_jsx("button", { onClick: () => onEdit(post.id), className: "text-left w-full hover:cursor-pointer p-0 m-0 border-0 bg-transparent group/title", children: _jsx("h3", { className: "font-bold text-dashboard-text text-sm tracking-tight group-hover/title:text-primary transition-colors truncate max-w-[200px] lg:max-w-[300px]", children: post.title.trim() }) }), _jsxs("p", { className: "text-[9px] font-mono text-dashboard-text-secondary/50 uppercase tracking-tight truncate max-w-[150px]", children: ["/", post.slug] })] })] }) }), _jsx("td", { className: "px-8 py-4 hidden lg:table-cell", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: `size-8 rounded-lg flex items-center justify-center text-[10px] font-bold border transition-all overflow-hidden shrink-0 ${owner ? 'bg-primary text-white border-primary/20 shadow-lg shadow-primary/20' : 'bg-dashboard-bg/50 text-dashboard-text-secondary border-dashboard-border/60'}`, children: author.image ? (_jsx("img", { src: author.image, alt: author.name, className: "size-full object-cover", crossOrigin: "anonymous" })) : initials }), _jsxs("span", { className: `text-[10px] font-bold uppercase tracking-tight truncate max-w-[100px] ${owner ? 'text-primary' : 'text-dashboard-text/70'}`, children: [author.name, owner && _jsx("span", { className: "opacity-60 ml-0.5", children: "(YOU)" })] })] }) }), _jsx("td", { className: "px-8 py-4 hidden xl:table-cell", children: _jsxs("span", { className: "text-[10px] font-bold text-primary/80 uppercase tracking-widest flex items-center gap-1.5", children: [_jsx(Tag, { size: 10 }), post.category || 'Article'] }) }), _jsx("td", { className: "px-8 py-4", children: _jsx(LanguageFlags, { post: post }) }), _jsx("td", { className: "px-8 py-4", children: _jsx("span", { className: `inline-flex items-center px-3 py-1 rounded-full text-[9px] font-bold uppercase tracking-wider border backdrop-blur-sm shadow-sm ${getStatusBadgeColor(post.status)}`, children: post.status === 'not-translated' ? 'Edition Missing' : post.status }) }), _jsx("td", { className: "px-8 py-4 hidden md:table-cell", children: _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-[11px] font-semibold text-dashboard-text/80 uppercase tracking-tight", children: formatDate(post.updatedAt, locale) }), _jsx("span", { className: "text-[9px] font-bold text-dashboard-text-secondary/50 uppercase tracking-widest", children: "Last Edit" })] }) }), _jsx("td", { className: "px-8 py-4 text-right", children: owner ? (_jsx("div", { className: "flex items-center justify-end", children: _jsx(PostActionsMenu, { onEdit: () => onEdit(post.id), onPreview: () => onPreview(post.id), onDuplicate: () => onDuplicate(post.id), onDelete: () => onDelete(post.id) }) })) : (_jsx("span", { className: "text-[9px] font-bold text-dashboard-text-secondary/30 uppercase tracking-widest italic", children: "View Only" })) })] }, post.id));
62
+ }) })] }) }) }));
80
63
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Settings View - Development/Installation Screen
2
+ * Settings View - Theme Configuration
3
3
  * Allows manual configuration of plugin settings (darkMode, backgroundColors)
4
4
  */
5
5
  export interface SettingsViewProps {
@@ -1 +1 @@
1
- {"version":3,"file":"SettingsView.d.ts","sourceRoot":"","sources":["../../../src/views/Settings/SettingsView.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,2CAyRjE"}
1
+ {"version":3,"file":"SettingsView.d.ts","sourceRoot":"","sources":["../../../src/views/Settings/SettingsView.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,2CAsKjE"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Settings View - Development/Installation Screen
2
+ * Settings View - Theme Configuration
3
3
  * Allows manual configuration of plugin settings (darkMode, backgroundColors)
4
4
  */
5
5
  'use client';
@@ -45,50 +45,31 @@ export function SettingsView({ siteId, locale }) {
45
45
  const handleSave = () => {
46
46
  if (typeof window === 'undefined')
47
47
  return;
48
- // Initialize window global if needed
49
- if (!window.__JHITS_PLUGIN_PROPS__) {
50
- window.__JHITS_PLUGIN_PROPS__ = {};
51
- }
52
48
  // Update configuration
53
- window.__JHITS_PLUGIN_PROPS__['plugin-blog'] = {
54
- ...(window.__JHITS_PLUGIN_PROPS__['plugin-blog'] || {}),
49
+ const config = {
55
50
  darkMode,
56
51
  backgroundColors: {
57
52
  light: lightBg,
58
53
  dark: darkBg,
59
54
  },
60
55
  };
61
- // Also save to localStorage for persistence
62
- try {
63
- localStorage.setItem('__JHITS_PLUGIN_BLOG_CONFIG__', JSON.stringify({
64
- darkMode,
65
- backgroundColors: {
66
- light: lightBg,
67
- dark: darkBg,
68
- },
69
- }));
70
- }
71
- catch (e) {
72
- console.warn('[SettingsView] Failed to save to localStorage:', e);
56
+ if (!window.__JHITS_PLUGIN_PROPS__) {
57
+ window.__JHITS_PLUGIN_PROPS__ = {};
73
58
  }
59
+ window.__JHITS_PLUGIN_PROPS__['plugin-blog'] = {
60
+ ...(window.__JHITS_PLUGIN_PROPS__['plugin-blog'] || {}),
61
+ ...config
62
+ };
63
+ localStorage.setItem('__JHITS_PLUGIN_BLOG_CONFIG__', JSON.stringify(config));
74
64
  setSaved(true);
75
65
  setTimeout(() => setSaved(false), 2000);
76
- // Trigger a custom event to notify other components
77
- window.dispatchEvent(new CustomEvent('blog-plugin-config-updated', {
78
- detail: { darkMode, backgroundColors: { light: lightBg, dark: darkBg } }
79
- }));
80
- console.log('[SettingsView] Configuration saved:', {
81
- darkMode,
82
- backgroundColors: { light: lightBg, dark: darkBg },
83
- });
66
+ window.dispatchEvent(new CustomEvent('blog-plugin-config-updated', { detail: config }));
84
67
  };
85
- // Reset to defaults
86
68
  const handleReset = () => {
87
69
  setDarkMode(true);
88
70
  setLightBg('#ffffff');
89
71
  setDarkBg('#171717');
90
72
  };
91
- // Load from localStorage on mount
92
73
  useEffect(() => {
93
74
  try {
94
75
  const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
@@ -99,15 +80,7 @@ export function SettingsView({ siteId, locale }) {
99
80
  setDarkBg(config.backgroundColors?.dark ?? '#171717');
100
81
  }
101
82
  }
102
- catch (e) {
103
- console.warn('[SettingsView] Failed to load from localStorage:', e);
104
- }
83
+ catch (e) { }
105
84
  }, []);
106
- return (_jsx("div", { className: "min-h-screen bg-neutral-50 dark:bg-neutral-900 p-8", children: _jsxs("div", { className: "max-w-4xl mx-auto", children: [_jsxs("div", { className: "mb-8", children: [_jsx("h1", { className: "text-4xl font-black uppercase tracking-tighter text-neutral-950 dark:text-white mb-2", children: "Blog Plugin Settings" }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: "Configure editor appearance and behavior. Changes are applied immediately." })] }), _jsxs("div", { className: "bg-white dark:bg-neutral-800 rounded-[2.5rem] border border-neutral-200 dark:border-neutral-700 shadow-lg p-8", children: [_jsx("div", { className: "mb-8 pb-8 border-b border-neutral-200 dark:border-neutral-700", children: _jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [darkMode ? (_jsx(Moon, { className: "size-5 text-neutral-600 dark:text-neutral-400" })) : (_jsx(Sun, { className: "size-5 text-neutral-600 dark:text-neutral-400" })), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Dark Mode" }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-500 mt-1", children: "Enable dark mode for editor content area and wrappers" })] })] }), _jsx("button", { onClick: () => setDarkMode(!darkMode), className: `relative inline-flex h-6 w-11 items-center rounded-full transition-colors ${darkMode
107
- ? 'bg-primary'
108
- : 'bg-neutral-300 dark:bg-neutral-600'}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${darkMode ? 'translate-x-6' : 'translate-x-1'}` }) })] }) }), _jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Palette, { className: "size-5 text-neutral-600 dark:text-neutral-400" }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Background Colors" }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-500 mt-1", children: "Set custom background colors for the editor canvas" })] })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsxs("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-2", children: ["Light Mode Background ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "text", value: lightBg, onChange: (e) => setLightBg(e.target.value), placeholder: "#ffffff", className: "flex-1 bg-dashboard-card border border-dashboard-border p-4 rounded-2xl text-sm font-bold outline-none focus:border-primary transition-all text-dashboard-text" }), _jsx("div", { className: "w-16 h-16 rounded-xl border-2 border-neutral-200 dark:border-neutral-700", style: { backgroundColor: lightBg } })] }), _jsx("p", { className: "text-xs text-neutral-400 dark:text-neutral-600 mt-1", children: "CSS color value (hex, rgb, or named color)" })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-2", children: ["Dark Mode Background ", _jsx("span", { className: "text-neutral-400", children: "(Optional)" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "text", value: darkBg, onChange: (e) => setDarkBg(e.target.value), placeholder: "#171717", disabled: !darkMode, className: `flex-1 bg-white dark:bg-neutral-900/50 border border-neutral-300 dark:border-neutral-700 p-4 rounded-2xl text-sm font-bold outline-none focus:border-primary transition-all dark:text-neutral-100 ${!darkMode ? 'opacity-50 cursor-not-allowed' : ''}` }), _jsx("div", { className: `w-16 h-16 rounded-xl border-2 border-neutral-200 dark:border-neutral-700 ${!darkMode ? 'opacity-50' : ''}`, style: { backgroundColor: darkBg } })] }), _jsx("p", { className: "text-xs text-neutral-400 dark:text-neutral-600 mt-1", children: "Only used when dark mode is enabled" })] })] })] }), _jsxs("div", { className: "mb-8 p-6 bg-neutral-50 dark:bg-neutral-900/50 rounded-2xl border border-neutral-200 dark:border-neutral-700", children: [_jsx("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-3", children: "Preview" }), _jsx("div", { className: "h-32 rounded-xl border-2 border-dashed border-neutral-300 dark:border-neutral-700 flex items-center justify-center", style: {
109
- backgroundColor: darkMode ? darkBg : lightBg,
110
- }, children: _jsx("span", { className: "text-xs font-bold uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Editor Canvas Preview" }) })] }), _jsxs("div", { className: "flex items-center justify-between pt-6 border-t border-neutral-200 dark:border-neutral-700", children: [_jsxs("button", { onClick: handleReset, className: "px-6 py-3 rounded-full border border-neutral-300 dark:border-neutral-700 bg-white dark:bg-neutral-900/50 text-sm font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors flex items-center gap-2", children: [_jsx(RotateCcw, { className: "size-4" }), "Reset"] }), _jsxs("button", { onClick: handleSave, disabled: !hasChanges, className: `px-6 py-3 rounded-full text-sm font-black uppercase tracking-widest transition-all flex items-center gap-2 ${hasChanges
111
- ? 'bg-primary text-white hover:bg-primary/90 shadow-lg shadow-primary/20'
112
- : 'bg-neutral-200 dark:bg-neutral-700 text-neutral-400 dark:text-neutral-600 cursor-not-allowed'}`, children: [_jsx(Save, { className: "size-4" }), saved ? 'Saved!' : 'Save Changes'] })] })] }), _jsxs("div", { className: "mt-6 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-2xl p-6", children: [_jsx("h3", { className: "text-sm font-black uppercase tracking-widest text-blue-900 dark:text-blue-300 mb-2", children: "How It Works" }), _jsxs("ul", { className: "text-xs text-blue-800 dark:text-blue-400 space-y-1 list-disc list-inside", children: [_jsxs("li", { children: ["Changes are saved to ", _jsx("code", { className: "bg-blue-100 dark:bg-blue-900/50 px-1 rounded", children: "window.__JHITS_PLUGIN_PROPS__" }), " and localStorage"] }), _jsx("li", { children: "Configuration persists across page refreshes" }), _jsx("li", { children: "To apply changes in the editor, navigate to a post editor page" }), _jsx("li", { children: "For production, configure these settings in your client app's blog config file" })] })] })] }) }));
85
+ return (_jsx("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "mb-8 px-2", children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Blog ", _jsx("span", { className: "text-primary italic", children: "Configuration" })] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium opacity-80", children: "Customize your editorial environment and visual preferences." })] }), _jsxs("div", { className: "bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm p-8 lg:p-10", children: [_jsx("div", { className: "mb-10 pb-8 border-b border-dashboard-border/30", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "size-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary border border-primary/20", children: darkMode ? _jsx(Moon, { size: 20 }) : _jsx(Sun, { size: 20 }) }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-bold text-dashboard-text uppercase tracking-wider block", children: "Visual Mode" }), _jsx("p", { className: "text-xs text-dashboard-text-secondary mt-0.5 opacity-70", children: "Synchronize editor with system preference" })] })] }), _jsx("button", { onClick: () => setDarkMode(!darkMode), className: `relative inline-flex h-6 w-11 items-center rounded-full transition-all ${darkMode ? 'bg-primary shadow-lg shadow-primary/20' : 'bg-neutral-300 dark:bg-neutral-700'}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${darkMode ? 'translate-x-6' : 'translate-x-1'}` }) })] }) }), _jsxs("div", { className: "mb-10", children: [_jsxs("div", { className: "flex items-center gap-4 mb-8", children: [_jsx("div", { className: "size-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500 border border-amber-500/20", children: _jsx(Palette, { size: 20 }) }), _jsx("label", { className: "text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Canvas Aesthetics" })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [_jsxs("div", { className: "space-y-3", children: [_jsx("label", { className: "block text-[10px] font-bold uppercase tracking-[0.2em] text-dashboard-text-secondary ml-1 opacity-60 text-primary", children: "Light Protocol" }), _jsx("input", { type: "text", value: lightBg, onChange: e => setLightBg(e.target.value), className: "w-full bg-dashboard-bg/50 border border-dashboard-border/40 p-4 rounded-2xl text-sm font-semibold outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 text-dashboard-text transition-all" })] }), _jsxs("div", { className: "space-y-3", children: [_jsx("label", { className: "block text-[10px] font-bold uppercase tracking-[0.2em] text-dashboard-text-secondary ml-1 opacity-60 text-primary", children: "Dark Protocol" }), _jsx("input", { type: "text", value: darkBg, onChange: e => setDarkBg(e.target.value), disabled: !darkMode, className: "w-full bg-dashboard-bg/50 border border-dashboard-border/40 p-4 rounded-2xl text-sm font-semibold outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 text-dashboard-text disabled:opacity-30 transition-all" })] })] })] }), _jsxs("div", { className: "flex items-center justify-between pt-8 border-t border-dashboard-border/30", children: [_jsxs("button", { onClick: handleReset, className: "px-6 py-3.5 rounded-2xl border border-dashboard-border/60 text-xs font-bold uppercase tracking-widest text-dashboard-text-secondary hover:text-dashboard-text hover:bg-dashboard-bg/50 transition-all active:scale-95", children: [_jsx(RotateCcw, { size: 14, className: "inline mr-2" }), " Restore Factory"] }), _jsxs("button", { onClick: handleSave, disabled: !hasChanges, className: `px-8 py-3.5 rounded-2xl text-xs font-bold uppercase tracking-widest transition-all flex items-center gap-2 ${hasChanges ? 'bg-primary text-white shadow-xl shadow-primary/25 hover:scale-[1.02]' : 'bg-neutral-100 dark:bg-neutral-800 text-dashboard-text-secondary opacity-40 cursor-not-allowed'}`, children: [_jsx(Save, { size: 16 }), " ", saved ? 'System Updated' : 'Commit Changes'] })] })] })] }) }));
113
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"SlugSEOManagerView.d.ts","sourceRoot":"","sources":["../../../src/views/SlugSEO/SlugSEOManagerView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,uBAAuB,2CA2ErF"}
1
+ {"version":3,"file":"SlugSEOManagerView.d.ts","sourceRoot":"","sources":["../../../src/views/SlugSEO/SlugSEOManagerView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,uBAAuB,2CA2FrF"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  'use client';
7
7
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
- import { Search, Link2, FileText } from 'lucide-react';
8
+ import { Search, Link2, FileText, Globe } from 'lucide-react';
9
9
  export function SlugSEOManagerView({ postId, siteId, locale }) {
10
- return (_jsx("div", { className: "h-full w-full bg-white dark:bg-neutral-900 p-8 overflow-y-auto", children: _jsxs("div", { className: "max-w-4xl mx-auto", children: [_jsx("h1", { className: "text-3xl font-black text-neutral-950 dark:text-white uppercase tracking-tighter mb-2", children: "Slug & SEO Manager" }), _jsx("p", { className: "text-sm text-neutral-500 dark:text-neutral-400 mb-8", children: postId ? `Managing SEO for post: ${postId}` : 'Manage URL slugs and SEO metadata' }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "p-6 bg-neutral-100 dark:bg-neutral-800/50 rounded-[2.5rem] border border-neutral-300 dark:border-neutral-700", children: [_jsx("label", { className: "block text-sm font-black text-neutral-950 dark:text-white uppercase tracking-tight mb-3", children: "URL Slug" }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Link2, { className: "text-neutral-400 size-5" }), _jsx("input", { type: "text", placeholder: "post-url-slug", className: "flex-1 px-4 py-3 bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-700 rounded-2xl text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary outline-none" })] }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-400 mt-2", children: "Collision detection will appear here" })] }), _jsxs("div", { className: "p-6 bg-neutral-100 dark:bg-neutral-800/50 rounded-[2.5rem] border border-neutral-300 dark:border-neutral-700", children: [_jsx("label", { className: "block text-sm font-black text-neutral-950 dark:text-white uppercase tracking-tight mb-3", children: "Search Result Preview" }), _jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl p-4 border border-neutral-300 dark:border-neutral-700", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Search, { size: 16, className: "text-neutral-400" }), _jsx("span", { className: "text-xs text-neutral-500", children: "Google Search Result" })] }), _jsxs("div", { className: "space-y-1", children: [_jsx("h3", { className: "text-lg text-blue-600 dark:text-blue-400 hover:underline cursor-pointer", children: "Post Title Will Appear Here" }), _jsx("p", { className: "text-sm text-green-700 dark:text-green-400", children: "https://example.com/blog/post-url-slug" }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: "Meta description will appear here. This is what users see in search results." })] })] })] }), _jsxs("div", { className: "p-6 bg-neutral-100 dark:bg-neutral-800/50 rounded-[2.5rem] border border-neutral-300 dark:border-neutral-700", children: [_jsx("label", { className: "block text-sm font-black text-neutral-950 dark:text-white uppercase tracking-tight mb-3", children: "Meta Description" }), _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(FileText, { className: "text-neutral-400 size-5 mt-1" }), _jsx("textarea", { placeholder: "Enter meta description for search engines...", rows: 4, className: "flex-1 px-4 py-3 bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-700 rounded-2xl text-sm focus:ring-2 focus:ring-primary/20 focus:border-primary outline-none resize-none" })] }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-400 mt-2", children: "0 / 160 characters" })] })] })] }) }));
10
+ return (_jsx("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent overflow-y-auto", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "mb-8 px-2", children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Search ", _jsx("span", { className: "text-primary italic", children: "&" }), " Discovery"] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium opacity-80", children: postId ? `Optimizing visibility for: ${postId}` : 'Manage URL architecture and search engine metadata' })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(Link2, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "URL Identifier" })] }), _jsx("div", { className: "flex items-center gap-3", children: _jsx("input", { type: "text", placeholder: "article-url-slug", className: "flex-1 px-5 py-4 bg-dashboard-bg/50 border border-dashboard-border/40 rounded-2xl text-sm font-semibold text-dashboard-text outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 transition-all" }) }), _jsx("p", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest mt-3 ml-1 opacity-50", children: "Automatic collision detection active" })] }), _jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(Search, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Search Engine Preview" })] }), _jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl p-6 border border-neutral-200 dark:border-neutral-800 shadow-inner", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx("div", { className: "size-4 rounded-full bg-neutral-100 dark:bg-neutral-800 flex items-center justify-center", children: _jsx(Globe, { size: 10, className: "text-neutral-400" }) }), _jsx("span", { className: "text-[10px] font-bold text-neutral-400 uppercase tracking-widest", children: "Global Result" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("h3", { className: "text-xl text-blue-600 dark:text-blue-400 font-medium hover:underline cursor-pointer leading-tight", children: "Publication Title Will Appear Here" }), _jsx("p", { className: "text-sm text-emerald-700 dark:text-emerald-500 font-medium", children: "https://yourdomain.com/blog/article-url-slug" }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 line-clamp-2", children: "Meta description will appear here. This is the snippet users see when discovering your content via search protocols." })] })] })] }), _jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(FileText, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Metadata Summary" })] }), _jsx("div", { className: "flex items-start gap-3", children: _jsx("textarea", { placeholder: "Enter meta description for indexing...", rows: 4, className: "flex-1 px-5 py-4 bg-dashboard-bg/50 border border-dashboard-border/40 rounded-2xl text-sm font-semibold text-dashboard-text outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 transition-all resize-none" }) }), _jsxs("div", { className: "flex justify-between items-center mt-3 px-1", children: [_jsx("p", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest opacity-50", children: "Recommended: 150-160 characters" }), _jsx("span", { className: "text-[10px] font-bold text-primary uppercase tracking-widest", children: "0 / 160" })] })] })] })] }) }));
11
11
  }