@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
@@ -5,9 +5,9 @@
5
5
 
6
6
  'use client';
7
7
 
8
- import React, { useState, useEffect } from 'react';
9
- import { Calendar, User, UserCheck } from 'lucide-react';
10
- import { Image } from '@jhits/plugin-images';
8
+ import React from 'react';
9
+ import { FileText, Tag, Activity } from 'lucide-react';
10
+ import { Image as PluginImage } from '@jhits/plugin-images';
11
11
  import { PostListItem, PostStatus } from '../../types/post';
12
12
  import { PostActionsMenu } from './PostActionsMenu';
13
13
  import { LanguageFlags } from './LanguageFlags';
@@ -25,17 +25,17 @@ export interface PostTableProps {
25
25
  function getStatusBadgeColor(status: PostStatus | 'not-translated') {
26
26
  switch (status) {
27
27
  case 'published':
28
- return 'bg-green-500/10 text-green-700 dark:text-green-400 border-green-500/20';
28
+ return 'bg-emerald-500 text-white border-emerald-400 shadow-sm';
29
29
  case 'draft':
30
- return 'bg-amber-500/10 text-amber-700 dark:text-amber-400 border-amber-500/20';
30
+ return 'bg-amber-500 text-white border-amber-400 shadow-sm';
31
31
  case 'scheduled':
32
- return 'bg-blue-500/10 text-blue-700 dark:text-blue-400 border-blue-500/20';
32
+ return 'bg-blue-500 text-white border-blue-400 shadow-sm';
33
33
  case 'archived':
34
- return 'bg-neutral-500/10 text-neutral-700 dark:text-neutral-400 border-neutral-500/20';
34
+ return 'bg-neutral-500 text-white border-neutral-400';
35
35
  case 'not-translated':
36
- return 'bg-red-500/10 text-red-700 dark:text-red-400 border-red-500/20 italic';
36
+ return 'bg-red-500/10 text-red-500 border-red-500/20 italic';
37
37
  default:
38
- return 'bg-neutral-500/10 text-neutral-700 dark:text-neutral-400 border-neutral-500/20';
38
+ return 'bg-neutral-500/10 text-neutral-500 border-neutral-500/20';
39
39
  }
40
40
  }
41
41
 
@@ -58,184 +58,156 @@ export function PostTable({
58
58
  }: PostTableProps) {
59
59
  const { data: session, status: sessionStatus } = useSession();
60
60
  const currentUserId = (session?.user as any)?.id;
61
- const [userMap, setUserMap] = useState<Record<string, string>>({});
62
61
 
63
62
  // Helper function to check if user is the owner
64
63
  const isPostOwner = (post: PostListItem): boolean => {
65
- if (sessionStatus === 'loading') return false; // Don't show actions while loading
64
+ if (sessionStatus === 'loading') return false;
66
65
  if (!currentUserId || !post.authorId) return false;
67
- // Convert both to strings for comparison to handle ObjectId vs string
68
66
  return String(currentUserId) === String(post.authorId);
69
67
  };
70
68
 
71
- // Fetch users to map IDs to names
72
- useEffect(() => {
73
- const fetchUsers = async () => {
74
- try {
75
- const response = await fetch('/api/users');
76
- const users = await response.json();
77
- if (Array.isArray(users)) {
78
- const map: Record<string, string> = {};
79
- users.forEach((user: { _id: string; name?: string; email?: string }) => {
80
- const id = user._id?.toString();
81
- if (id) {
82
- map[id] = user.name || user.email || 'Unknown';
83
- }
84
- });
85
- setUserMap(map);
86
- }
87
- } catch (error) {
88
- console.error('Failed to fetch users:', error);
89
- }
90
- };
91
- fetchUsers();
92
- }, []);
93
-
94
- const getAuthorName = (authorId?: string) => {
95
- if (!authorId) return 'Unknown';
96
- return userMap[authorId] || authorId;
69
+ const getAuthorData = (post: PostListItem) => {
70
+ if (post.author) {
71
+ return {
72
+ name: post.author.name || 'Unknown Author',
73
+ image: post.author.image
74
+ };
75
+ }
76
+ return { name: 'Unknown Author' };
97
77
  };
98
78
 
99
79
  return (
100
- <div className="bg-neutral-100 dark:bg-neutral-800/50 rounded-[2.5rem] border border-neutral-300 dark:border-neutral-700 overflow-hidden">
101
- <div className="overflow-x-auto">
102
- <table className="w-full">
103
- <thead className="bg-neutral-200 dark:bg-neutral-900/50 border-b border-neutral-300 dark:border-neutral-700">
104
- <tr>
105
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
106
- Post
107
- </th>
108
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
109
- Author
110
- </th>
111
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
112
- Category
113
- </th>
114
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
115
- Languages
116
- </th>
117
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
118
- Status
119
- </th>
120
- <th className="px-6 py-4 text-left text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
121
- Last Modified
122
- </th>
123
- <th className="px-6 py-4 text-right text-[10px] font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400">
124
- Actions
125
- </th>
80
+ <div className="bg-dashboard-card/40 rounded-[2rem] overflow-hidden border border-dashboard-border/40 shadow-sm">
81
+ <div className="overflow-x-auto custom-scrollbar">
82
+ <table className="w-full text-left border-collapse min-w-[1000px] lg:min-w-0">
83
+ <thead>
84
+ <tr className="text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest border-b border-dashboard-border/40 bg-dashboard-bg/20">
85
+ <th className="px-8 py-5">Publication</th>
86
+ <th className="px-8 py-5 hidden lg:table-cell">Author</th>
87
+ <th className="px-8 py-5 hidden xl:table-cell">Category</th>
88
+ <th className="px-8 py-5">Editions</th>
89
+ <th className="px-8 py-5">Status</th>
90
+ <th className="px-8 py-5 hidden md:table-cell">Modified</th>
91
+ <th className="px-8 py-5 text-right">Actions</th>
126
92
  </tr>
127
93
  </thead>
128
- <tbody className="divide-y divide-neutral-300 dark:divide-neutral-700">
129
- {posts.map((post) => (
130
- <tr
131
- key={post.id}
132
- className="hover:bg-white dark:hover:bg-neutral-900/50 transition-colors cursor-pointer"
133
- >
134
- {/* Featured Image & Title */}
135
- <td className="px-6 py-4">
136
- <div className="flex items-center gap-4">
137
- {post.featuredImage ? (
138
- <div className="w-16 h-16 rounded-xl bg-neutral-200 dark:bg-neutral-700 overflow-hidden flex-shrink-0 relative">
139
- <Image
140
- id={post.featuredImage}
141
- alt={post.title}
142
- fill
143
- editable={false}
144
- className="w-full h-full object-cover"
145
- />
94
+ <tbody className="divide-y divide-dashboard-border/30">
95
+ {posts.map((post) => {
96
+ const owner = isPostOwner(post);
97
+ const author = getAuthorData(post);
98
+ const initials = author.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
99
+
100
+ return (
101
+ <tr
102
+ key={post.id}
103
+ className="group hover:bg-primary/[0.03] transition-colors"
104
+ >
105
+ {/* Featured Image & Title */}
106
+ <td className="px-8 py-4">
107
+ <div className="flex items-center gap-4">
108
+ {post.featuredImage ? (
109
+ <div className={`size-12 relative bg-dashboard-bg/50 rounded-xl overflow-hidden border transition-all shrink-0 ${
110
+ owner ? 'border-primary/30' : 'border-dashboard-border/60'
111
+ }`}>
112
+ <PluginImage
113
+ id={post.featuredImage}
114
+ alt={post.title}
115
+ fill
116
+ editable={false}
117
+ className="object-cover"
118
+ />
119
+ </div>
120
+ ) : (
121
+ <div className="size-12 rounded-xl bg-dashboard-bg/50 flex items-center justify-center border border-dashboard-border/60 opacity-20 shrink-0">
122
+ <FileText size={18} />
123
+ </div>
124
+ )}
125
+ <div className="min-w-0">
126
+ <button
127
+ onClick={() => onEdit(post.id)}
128
+ className="text-left w-full hover:cursor-pointer p-0 m-0 border-0 bg-transparent group/title"
129
+ >
130
+ <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]">
131
+ {post.title.trim()}
132
+ </h3>
133
+ </button>
134
+ <p className="text-[9px] font-mono text-dashboard-text-secondary/50 uppercase tracking-tight truncate max-w-[150px]">
135
+ /{post.slug}
136
+ </p>
146
137
  </div>
147
- ) : (
148
- <div className="w-16 h-16 rounded-xl bg-neutral-200 dark:bg-neutral-700 flex items-center justify-center flex-shrink-0">
149
- <span className="text-xs text-neutral-400">No Image</span>
138
+ </div>
139
+ </td>
140
+
141
+ {/* Author */}
142
+ <td className="px-8 py-4 hidden lg:table-cell">
143
+ <div className="flex items-center gap-3">
144
+ <div className={`size-8 rounded-lg flex items-center justify-center text-[10px] font-bold border transition-all overflow-hidden shrink-0 ${
145
+ 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'
146
+ }`}>
147
+ {author.image ? (
148
+ <img src={author.image} alt={author.name} className="size-full object-cover" crossOrigin="anonymous" />
149
+ ) : initials}
150
150
  </div>
151
- )}
152
- <div className="min-w-0 flex-1">
153
- <button
154
- onClick={() => onEdit(post.id)}
155
- className="text-left w-full hover:cursor-pointer p-0 m-0 border-0 bg-transparent"
156
- >
157
- <h3 className="font-bold hover:underline text-neutral-950 dark:text-white mb-1 line-clamp-1 text-left">
158
- {post.title.trim()}
159
- </h3>
160
- </button>
161
- <p className="text-xs text-neutral-500 dark:text-neutral-400 font-mono text-left">
162
- /{post.slug}
163
- </p>
151
+ <span className={`text-[10px] font-bold uppercase tracking-tight truncate max-w-[100px] ${owner ? 'text-primary' : 'text-dashboard-text/70'}`}>
152
+ {author.name}
153
+ {owner && <span className="opacity-60 ml-0.5">(YOU)</span>}
154
+ </span>
164
155
  </div>
165
- </div>
166
- </td>
156
+ </td>
167
157
 
168
- {/* Author */}
169
- <td className="px-6 py-4">
170
- <div className="flex items-center gap-2">
171
- {isPostOwner(post) ? (
172
- <UserCheck size={14} className="text-primary" />
173
- ) : (
174
- <User size={14} className="text-neutral-400" />
175
- )}
176
- <span className={`text-sm ${isPostOwner(post) ? 'text-primary font-semibold' : 'text-neutral-600 dark:text-neutral-400'}`}>
177
- {getAuthorName(post.authorId)}
178
- {isPostOwner(post) && (
179
- <span className="ml-2 text-xs text-primary/70">(Jij)</span>
180
- )}
158
+ {/* Category */}
159
+ <td className="px-8 py-4 hidden xl:table-cell">
160
+ <span className="text-[10px] font-bold text-primary/80 uppercase tracking-widest flex items-center gap-1.5">
161
+ <Tag size={10} />
162
+ {post.category || 'Article'}
181
163
  </span>
182
- </div>
183
- </td>
184
-
185
- {/* Category */}
186
- <td className="px-6 py-4">
187
- <span className="text-sm text-neutral-600 dark:text-neutral-400">
188
- {post.category || 'Uncategorized'}
189
- </span>
190
- </td>
191
-
192
- {/* Languages */}
193
- <td className="px-6 py-4">
194
- <LanguageFlags post={post} />
195
- </td>
196
-
197
- {/* Status Badge */}
198
- <td className="px-6 py-4">
199
- <span
200
- className={`inline-flex items-center px-3 py-1 rounded-full text-[10px] font-black uppercase tracking-wider border ${getStatusBadgeColor(post.status)}`}
201
- >
202
- {post.status}
203
- </span>
204
- </td>
205
-
206
- {/* Last Modified */}
207
- <td className="px-6 py-4">
208
- <div className="flex items-center gap-2">
209
- <Calendar size={14} className="text-neutral-400" />
210
- <span className="text-sm text-neutral-600 dark:text-neutral-400">
211
- {formatDate(post.updatedAt, locale)}
164
+ </td>
165
+
166
+ {/* Languages */}
167
+ <td className="px-8 py-4">
168
+ <LanguageFlags post={post} />
169
+ </td>
170
+
171
+ {/* Status Badge */}
172
+ <td className="px-8 py-4">
173
+ <span
174
+ 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)}`}
175
+ >
176
+ {post.status === 'not-translated' ? 'Edition Missing' : post.status}
212
177
  </span>
213
- </div>
214
- </td>
215
-
216
- {/* Actions Menu - Only show for own posts */}
217
- <td className="px-6 py-4">
218
- {isPostOwner(post) ? (
219
- <div className="flex items-center justify-end">
220
- <PostActionsMenu
221
- onEdit={() => onEdit(post.id)}
222
- onPreview={() => onPreview(post.id)}
223
- onDuplicate={() => onDuplicate(post.id)}
224
- onDelete={() => onDelete(post.id)}
225
- />
226
- </div>
227
- ) : (
228
- <div className="flex items-center justify-end text-neutral-400 text-xs">
229
- Alleen auteur
178
+ </td>
179
+
180
+ {/* Last Modified */}
181
+ <td className="px-8 py-4 hidden md:table-cell">
182
+ <div className="flex flex-col">
183
+ <span className="text-[11px] font-semibold text-dashboard-text/80 uppercase tracking-tight">
184
+ {formatDate(post.updatedAt, locale)}
185
+ </span>
186
+ <span className="text-[9px] font-bold text-dashboard-text-secondary/50 uppercase tracking-widest">Last Edit</span>
230
187
  </div>
231
- )}
232
- </td>
233
- </tr>
234
- ))}
188
+ </td>
189
+
190
+ {/* Actions Menu */}
191
+ <td className="px-8 py-4 text-right">
192
+ {owner ? (
193
+ <div className="flex items-center justify-end">
194
+ <PostActionsMenu
195
+ onEdit={() => onEdit(post.id)}
196
+ onPreview={() => onPreview(post.id)}
197
+ onDuplicate={() => onDuplicate(post.id)}
198
+ onDelete={() => onDelete(post.id)}
199
+ />
200
+ </div>
201
+ ) : (
202
+ <span className="text-[9px] font-bold text-dashboard-text-secondary/30 uppercase tracking-widest italic">View Only</span>
203
+ )}
204
+ </td>
205
+ </tr>
206
+ );
207
+ })}
235
208
  </tbody>
236
209
  </table>
237
210
  </div>
238
211
  </div>
239
212
  );
240
213
  }
241
-