@jhits/plugin-blog 0.0.18 → 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 -500
  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 -604
  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,215 +1,165 @@
1
1
  /**
2
2
  * Editor Context
3
- * React Context for managing editor state
4
- * Multi-Tenant: Accepts custom blocks from client applications
3
+ * Enhanced with language management and simplified state handling
5
4
  */
6
5
  'use client';
7
6
  import { jsx as _jsx } from "react/jsx-runtime";
8
- import { createContext, useContext, useReducer, useCallback, useMemo, useEffect, useRef, useState } from 'react';
7
+ import { createContext, useContext, useReducer, useMemo, useEffect, useRef, useState } from 'react';
9
8
  import { editorReducer } from './reducer';
10
9
  import { initialEditorState } from './types';
10
+ import { apiToBlogPost } from '../lib/mappers/apiMapper';
11
11
  import { blockRegistry } from '../registry/BlockRegistry';
12
12
  import { registerLayoutBlocks } from '../lib/layouts/registerLayoutBlocks';
13
- // Create the context
13
+ const API_BASE_URL = process.env.NEXT_PUBLIC_DASHBOARD_URL || 'http://localhost:3001';
14
14
  const EditorContext = createContext(null);
15
- /**
16
- * Editor Provider
17
- * Provides editor state and actions to child components
18
- * Automatically registers client-provided blocks on mount
19
- */
20
- export function EditorProvider({ children, initialState, onSave, customBlocks = [], darkMode = true, backgroundColors }) {
21
- // Register core layout blocks on mount
22
- useEffect(() => {
23
- registerLayoutBlocks();
24
- }, []);
25
- // Register client blocks on mount
26
- useEffect(() => {
27
- if (customBlocks && customBlocks.length > 0) {
28
- try {
29
- blockRegistry.registerClientBlocks(customBlocks);
30
- }
31
- catch (error) {
32
- console.error('[EditorContext] Failed to register custom blocks:', error);
33
- }
34
- }
35
- }, [customBlocks]);
15
+ export function EditorProvider({ children, initialState, onSave, customBlocks = [], darkMode = false, backgroundColors, translations }) {
16
+ useEffect(() => { registerLayoutBlocks(); }, []);
17
+ useEffect(() => { if (customBlocks?.length)
18
+ blockRegistry.registerClientBlocks(customBlocks); }, [customBlocks]);
36
19
  const [state, dispatch] = useReducer(editorReducer, { ...initialEditorState, ...initialState });
37
- // Use a ref to always have access to the latest state in callbacks
20
+ const [user, setUser] = useState(null);
38
21
  const stateRef = useRef(state);
39
22
  stateRef.current = state;
40
- // History state for undo/redo
23
+ // Language Management
24
+ const [availableLanguages, setAvailableLanguages] = useState([]);
25
+ useEffect(() => {
26
+ const fetchUser = async () => {
27
+ try {
28
+ const res = await fetch(`${API_BASE_URL}/api/me`);
29
+ if (res.ok) {
30
+ const data = await res.json();
31
+ if (data.user)
32
+ setUser(data.user);
33
+ }
34
+ }
35
+ catch (e) { }
36
+ };
37
+ fetchUser();
38
+ }, []);
39
+ // History logic (Simplified)
41
40
  const [history, setHistory] = useState([]);
42
41
  const [historyIndex, setHistoryIndex] = useState(-1);
43
42
  const isRestoringRef = useRef(false);
44
- const MAX_HISTORY = 50; // Limit history to prevent memory issues
45
- // Save current state to history after state changes (but not during undo/redo)
46
- // Debounce history updates to avoid excessive re-renders
47
- const historyTimeoutRef = useRef(null);
48
43
  useEffect(() => {
49
44
  if (isRestoringRef.current) {
50
45
  isRestoringRef.current = false;
51
46
  return;
52
47
  }
53
- // Clear existing timeout
54
- if (historyTimeoutRef.current) {
55
- clearTimeout(historyTimeoutRef.current);
56
- }
57
- // Debounce history updates to reduce re-renders
58
- historyTimeoutRef.current = setTimeout(() => {
59
- // Save current state to history
48
+ const timer = setTimeout(() => {
60
49
  setHistory(prev => {
61
- const newHistory = [...prev];
62
- // Remove any future history if we're not at the end
63
- if (historyIndex < newHistory.length - 1) {
64
- newHistory.splice(historyIndex + 1);
65
- }
66
- // Add current state
67
- newHistory.push({ ...state });
68
- // Limit history size
69
- if (newHistory.length > MAX_HISTORY) {
70
- newHistory.shift();
71
- return newHistory;
72
- }
73
- return newHistory;
50
+ const next = prev.slice(0, historyIndex + 1);
51
+ next.push({ ...state });
52
+ return next.slice(-50);
74
53
  });
75
- setHistoryIndex(prev => {
76
- const newIndex = prev + 1;
77
- return newIndex >= MAX_HISTORY ? MAX_HISTORY - 1 : newIndex;
78
- });
79
- }, 300); // Debounce by 300ms
80
- return () => {
81
- if (historyTimeoutRef.current) {
82
- clearTimeout(historyTimeoutRef.current);
54
+ setHistoryIndex(prev => Math.min(prev + 1, 49));
55
+ }, 300);
56
+ return () => clearTimeout(timer);
57
+ }, [state.blocks, state.title, state.slug]);
58
+ const helpers = useMemo(() => ({
59
+ addBlock: (type, index, containerId) => {
60
+ const def = blockRegistry.get(type);
61
+ const block = {
62
+ id: `block-${Date.now()}`,
63
+ type,
64
+ data: { ...(def?.defaultData || {}) }
65
+ };
66
+ dispatch({ type: 'ADD_BLOCK', payload: { block, index, containerId } });
67
+ },
68
+ updateBlock: (id, data) => dispatch({ type: 'UPDATE_BLOCK', payload: { id, data } }),
69
+ deleteBlock: (id) => dispatch({ type: 'DELETE_BLOCK', payload: { id } }),
70
+ duplicateBlock: (id) => dispatch({ type: 'DUPLICATE_BLOCK', payload: { id } }),
71
+ moveBlock: (id, newIndex, containerId) => dispatch({ type: 'MOVE_BLOCK', payload: { id, newIndex, containerId } }),
72
+ loadPost: (post) => {
73
+ dispatch({ type: 'LOAD_POST', payload: post });
74
+ // 1. Collect all unique language keys from the post data
75
+ const createdLangs = new Set();
76
+ // From availableLanguages array (source of truth from API)
77
+ if (post.availableLanguages) {
78
+ post.availableLanguages.forEach(l => createdLangs.add(l));
83
79
  }
84
- };
85
- }, [state.blocks, state.title, state.slug, state.seo, state.metadata, state.status, historyIndex]);
86
- // Helper: Add a new block (supports nested containers)
87
- const addBlock = useCallback((type, index, containerId) => {
88
- const blockDefinition = blockRegistry.get(type);
89
- if (!blockDefinition) {
90
- console.warn(`Block type "${type}" not found in registry. Available types:`, blockRegistry.getAll().map(b => b.type).join(', '));
91
- return;
92
- }
93
- const newBlock = {
94
- id: `block-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
95
- type,
96
- data: { ...blockDefinition.defaultData },
97
- };
98
- dispatch({ type: 'ADD_BLOCK', payload: { block: newBlock, index, containerId } });
99
- }, []);
100
- // Helper: Update a block
101
- const updateBlock = useCallback((id, data) => {
102
- dispatch({ type: 'UPDATE_BLOCK', payload: { id, data } });
103
- }, []);
104
- // Helper: Delete a block
105
- const deleteBlock = useCallback((id) => {
106
- dispatch({ type: 'DELETE_BLOCK', payload: { id } });
107
- }, []);
108
- // Helper: Duplicate a block
109
- const duplicateBlock = useCallback((id) => {
110
- dispatch({ type: 'DUPLICATE_BLOCK', payload: { id } });
111
- }, []);
112
- // Helper: Move a block (supports nested containers)
113
- const moveBlock = useCallback((id, newIndex, containerId) => {
114
- dispatch({ type: 'MOVE_BLOCK', payload: { id, newIndex, containerId } });
115
- }, []);
116
- // Helper: Load a post
117
- const loadPost = useCallback((post) => {
118
- dispatch({ type: 'LOAD_POST', payload: post });
119
- }, []);
120
- // Helper: Reset editor
121
- const resetEditor = useCallback(() => {
122
- dispatch({ type: 'RESET_EDITOR' });
123
- }, []);
124
- // Helper: Save
125
- // Uses stateRef to always get the latest state, avoiding stale closure issues
126
- const save = useCallback(async (heroBlock) => {
127
- if (onSave) {
128
- // Use stateRef.current to get the absolute latest state
129
- // This ensures we don't have stale closure issues with React state updates
130
- await onSave(stateRef.current, heroBlock);
131
- dispatch({ type: 'MARK_CLEAN' });
132
- }
133
- }, [onSave]);
134
- // Helper: Undo
135
- const undo = useCallback(() => {
136
- if (historyIndex > 0 && history.length > 0) {
137
- const previousState = history[historyIndex - 1];
138
- if (previousState) {
80
+ // From languages summary keys (backup)
81
+ if (post.languages) {
82
+ Object.keys(post.languages).forEach(l => createdLangs.add(l));
83
+ }
84
+ // 2. Update state with the consolidated list
85
+ setAvailableLanguages(Array.from(createdLangs));
86
+ },
87
+ resetEditor: () => dispatch({ type: 'RESET_EDITOR' }),
88
+ save: async (heroBlock, statusOverride) => {
89
+ if (onSave) {
90
+ const currentState = { ...stateRef.current };
91
+ if (statusOverride)
92
+ currentState.status = statusOverride;
93
+ await onSave(currentState, heroBlock);
94
+ dispatch({ type: 'MARK_CLEAN' });
95
+ }
96
+ },
97
+ undo: () => {
98
+ if (historyIndex > 0) {
139
99
  isRestoringRef.current = true;
140
- setHistoryIndex(prev => prev - 1);
141
- dispatch({ type: 'LOAD_POST', payload: {
142
- id: previousState.postId || '',
143
- title: previousState.title,
144
- slug: previousState.slug,
145
- blocks: previousState.blocks,
146
- seo: previousState.seo,
147
- publication: {
148
- status: previousState.status,
149
- authorId: undefined,
150
- },
151
- metadata: previousState.metadata,
152
- createdAt: new Date().toISOString(),
153
- updatedAt: new Date().toISOString(),
154
- } });
100
+ const prev = history[historyIndex - 1];
101
+ setHistoryIndex(i => i - 1);
102
+ dispatch({ type: 'LOAD_POST', payload: prev });
155
103
  }
156
- }
157
- }, [history, historyIndex, dispatch]);
158
- // Helper: Redo
159
- const redo = useCallback(() => {
160
- if (historyIndex < history.length - 1) {
161
- const nextState = history[historyIndex + 1];
162
- if (nextState) {
104
+ },
105
+ redo: () => {
106
+ if (historyIndex < history.length - 1) {
163
107
  isRestoringRef.current = true;
164
- setHistoryIndex(prev => prev + 1);
165
- dispatch({ type: 'LOAD_POST', payload: {
166
- id: nextState.postId || '',
167
- title: nextState.title,
168
- slug: nextState.slug,
169
- blocks: nextState.blocks,
170
- seo: nextState.seo,
171
- publication: {
172
- status: nextState.status,
173
- authorId: undefined,
174
- },
175
- metadata: nextState.metadata,
176
- createdAt: new Date().toISOString(),
177
- updatedAt: new Date().toISOString(),
178
- } });
108
+ const next = history[historyIndex + 1];
109
+ setHistoryIndex(i => i + 1);
110
+ dispatch({ type: 'LOAD_POST', payload: next });
111
+ }
112
+ },
113
+ switchLanguage: async (newLang, postId) => {
114
+ // 1. Always update the current language in state first to show immediate UI feedback
115
+ dispatch({ type: 'SET_CURRENT_LANGUAGE', payload: newLang });
116
+ if (!postId) {
117
+ dispatch({ type: 'SET_STATUS', payload: 'draft' });
118
+ return;
119
+ }
120
+ // 2. Fetch the language version from the API
121
+ const fetchUrl = `${API_BASE_URL}/api/plugin-blog/${postId}?language=${newLang}&admin=true`;
122
+ const res = await fetch(fetchUrl);
123
+ if (res.ok) {
124
+ const data = await res.json();
125
+ const blogPost = apiToBlogPost(data);
126
+ // Update the available languages list from the source of truth
127
+ if (data.availableLanguages) {
128
+ setAvailableLanguages(data.availableLanguages);
129
+ }
130
+ // If this is a NEW translation (missing in the document),
131
+ // customize it so it's not a perfect clone of the primary language
132
+ if (data.isMissingTranslation) {
133
+ blogPost.publication.status = 'draft';
134
+ blogPost.title = `${blogPost.title} - ${newLang.toUpperCase()}`;
135
+ // Important: Mark as dirty so it can be saved as a new version
136
+ dispatch({ type: 'LOAD_POST', payload: blogPost });
137
+ dispatch({ type: 'MARK_DIRTY' });
138
+ }
139
+ else {
140
+ dispatch({ type: 'LOAD_POST', payload: blogPost });
141
+ dispatch({ type: 'MARK_CLEAN' });
142
+ }
179
143
  }
180
144
  }
181
- }, [history, historyIndex, dispatch]);
182
- // Memoize the context value
145
+ }), [onSave, history, historyIndex, state.postId]);
183
146
  const value = useMemo(() => ({
184
147
  state,
185
148
  dispatch,
186
149
  darkMode,
187
150
  backgroundColors,
188
- helpers: {
189
- addBlock,
190
- updateBlock,
191
- deleteBlock,
192
- duplicateBlock,
193
- moveBlock,
194
- loadPost,
195
- resetEditor,
196
- save,
197
- undo,
198
- redo,
199
- },
200
- canUndo: historyIndex > 0 && history.length > 0,
151
+ translations,
152
+ user,
153
+ helpers,
154
+ availableLanguages,
155
+ canUndo: historyIndex > 0,
201
156
  canRedo: historyIndex < history.length - 1,
202
- }), [state, dispatch, darkMode, backgroundColors, addBlock, updateBlock, deleteBlock, duplicateBlock, moveBlock, loadPost, resetEditor, save, undo, redo, historyIndex, history.length]);
157
+ }), [state, darkMode, backgroundColors, user, helpers, historyIndex, history.length, availableLanguages]);
203
158
  return _jsx(EditorContext.Provider, { value: value, children: children });
204
159
  }
205
- /**
206
- * Hook to access editor context
207
- * @throws Error if used outside EditorProvider
208
- */
209
160
  export function useEditor() {
210
161
  const context = useContext(EditorContext);
211
- if (!context) {
212
- throw new Error('useEditor must be used within an EditorProvider');
213
- }
162
+ if (!context)
163
+ throw new Error('useEditor must be used within EditorProvider');
214
164
  return context;
215
165
  }
@@ -1,11 +1,7 @@
1
1
  /**
2
2
  * Editor Reducer
3
- * Pure function that handles state transitions
3
+ * Pure function that handles state transitions using tree utilities
4
4
  */
5
5
  import { EditorState, EditorAction } from './types';
6
- /**
7
- * Editor Reducer
8
- * Handles all state transitions for the editor
9
- */
10
6
  export declare function editorReducer(state: EditorState, action: EditorAction): EditorState;
11
7
  //# sourceMappingURL=reducer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/state/reducer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,SAAS,CAAC;AAqUxE;;;GAGG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,YAAY,GACrB,WAAW,CAyWb"}
1
+ {"version":3,"file":"reducer.d.ts","sourceRoot":"","sources":["../../src/state/reducer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,SAAS,CAAC;AA+BxE,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,WAAW,CAsMnF"}