@jhits/plugin-blog 0.0.9 → 0.0.11

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 (276) hide show
  1. package/package.json +58 -59
  2. package/src/api/categories.ts +0 -43
  3. package/src/api/check-title.ts +0 -60
  4. package/src/api/config-handler.ts +0 -76
  5. package/src/api/handler.ts +0 -418
  6. package/src/api/index.ts +0 -33
  7. package/src/api/route.ts +0 -116
  8. package/src/api/router.ts +0 -128
  9. package/src/api-server.ts +0 -11
  10. package/src/config.ts +0 -161
  11. package/src/hooks/index.d.ts +0 -8
  12. package/src/hooks/index.d.ts.map +0 -1
  13. package/src/hooks/index.js +0 -7
  14. package/src/hooks/index.ts +0 -9
  15. package/src/hooks/useBlog.d.ts +0 -31
  16. package/src/hooks/useBlog.d.ts.map +0 -1
  17. package/src/hooks/useBlog.js +0 -57
  18. package/src/hooks/useBlog.ts +0 -85
  19. package/src/hooks/useBlogs.d.ts +0 -39
  20. package/src/hooks/useBlogs.d.ts.map +0 -1
  21. package/src/hooks/useBlogs.js +0 -82
  22. package/src/hooks/useBlogs.ts +0 -123
  23. package/src/hooks/useCategories.d.ts +0 -9
  24. package/src/hooks/useCategories.d.ts.map +0 -1
  25. package/src/hooks/useCategories.js +0 -70
  26. package/src/hooks/useCategories.ts +0 -76
  27. package/src/index.d.ts +0 -55
  28. package/src/index.d.ts.map +0 -1
  29. package/src/index.js +0 -228
  30. package/src/index.server.ts +0 -14
  31. package/src/index.tsx +0 -335
  32. package/src/init.d.ts +0 -40
  33. package/src/init.d.ts.map +0 -1
  34. package/src/init.js +0 -41
  35. package/src/init.tsx +0 -63
  36. package/src/lib/blocks/BlockRenderer.d.ts +0 -54
  37. package/src/lib/blocks/BlockRenderer.d.ts.map +0 -1
  38. package/src/lib/blocks/BlockRenderer.js +0 -54
  39. package/src/lib/blocks/BlockRenderer.tsx +0 -141
  40. package/src/lib/blocks/index.ts +0 -6
  41. package/src/lib/config-storage.d.ts +0 -30
  42. package/src/lib/config-storage.d.ts.map +0 -1
  43. package/src/lib/config-storage.js +0 -31
  44. package/src/lib/config-storage.ts +0 -65
  45. package/src/lib/index.ts +0 -9
  46. package/src/lib/layouts/blocks/ColumnsBlock.d.ts +0 -25
  47. package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +0 -1
  48. package/src/lib/layouts/blocks/ColumnsBlock.js +0 -182
  49. package/src/lib/layouts/blocks/ColumnsBlock.tsx +0 -298
  50. package/src/lib/layouts/blocks/ColumnsBlock.tsx.tmp +0 -81
  51. package/src/lib/layouts/blocks/SectionBlock.d.ts +0 -25
  52. package/src/lib/layouts/blocks/SectionBlock.d.ts.map +0 -1
  53. package/src/lib/layouts/blocks/SectionBlock.js +0 -44
  54. package/src/lib/layouts/blocks/SectionBlock.tsx +0 -104
  55. package/src/lib/layouts/blocks/index.ts +0 -8
  56. package/src/lib/layouts/index.d.ts +0 -23
  57. package/src/lib/layouts/index.d.ts.map +0 -1
  58. package/src/lib/layouts/index.js +0 -45
  59. package/src/lib/layouts/index.ts +0 -52
  60. package/src/lib/layouts/registerLayoutBlocks.d.ts +0 -9
  61. package/src/lib/layouts/registerLayoutBlocks.d.ts.map +0 -1
  62. package/src/lib/layouts/registerLayoutBlocks.js +0 -60
  63. package/src/lib/layouts/registerLayoutBlocks.ts +0 -64
  64. package/src/lib/mappers/apiMapper.d.ts +0 -66
  65. package/src/lib/mappers/apiMapper.d.ts.map +0 -1
  66. package/src/lib/mappers/apiMapper.js +0 -191
  67. package/src/lib/mappers/apiMapper.ts +0 -254
  68. package/src/lib/migration/index.ts +0 -6
  69. package/src/lib/migration/mapper.ts +0 -140
  70. package/src/lib/rich-text/RichTextEditor.d.ts +0 -45
  71. package/src/lib/rich-text/RichTextEditor.d.ts.map +0 -1
  72. package/src/lib/rich-text/RichTextEditor.js +0 -564
  73. package/src/lib/rich-text/RichTextEditor.tsx +0 -826
  74. package/src/lib/rich-text/RichTextPreview.d.ts +0 -16
  75. package/src/lib/rich-text/RichTextPreview.d.ts.map +0 -1
  76. package/src/lib/rich-text/RichTextPreview.js +0 -144
  77. package/src/lib/rich-text/RichTextPreview.tsx +0 -210
  78. package/src/lib/rich-text/index.d.ts +0 -9
  79. package/src/lib/rich-text/index.d.ts.map +0 -1
  80. package/src/lib/rich-text/index.js +0 -6
  81. package/src/lib/rich-text/index.ts +0 -10
  82. package/src/lib/utils/blockHelpers.d.ts +0 -23
  83. package/src/lib/utils/blockHelpers.d.ts.map +0 -1
  84. package/src/lib/utils/blockHelpers.js +0 -65
  85. package/src/lib/utils/blockHelpers.ts +0 -72
  86. package/src/lib/utils/configValidation.d.ts +0 -23
  87. package/src/lib/utils/configValidation.d.ts.map +0 -1
  88. package/src/lib/utils/configValidation.js +0 -113
  89. package/src/lib/utils/configValidation.ts +0 -137
  90. package/src/lib/utils/index.ts +0 -8
  91. package/src/lib/utils/slugify.ts +0 -79
  92. package/src/registry/BlockRegistry.d.ts +0 -62
  93. package/src/registry/BlockRegistry.d.ts.map +0 -1
  94. package/src/registry/BlockRegistry.js +0 -112
  95. package/src/registry/BlockRegistry.ts +0 -139
  96. package/src/registry/index.d.ts +0 -6
  97. package/src/registry/index.d.ts.map +0 -1
  98. package/src/registry/index.js +0 -4
  99. package/src/registry/index.ts +0 -11
  100. package/src/state/EditorContext.d.ts +0 -45
  101. package/src/state/EditorContext.d.ts.map +0 -1
  102. package/src/state/EditorContext.js +0 -215
  103. package/src/state/EditorContext.tsx +0 -283
  104. package/src/state/index.d.ts +0 -7
  105. package/src/state/index.d.ts.map +0 -1
  106. package/src/state/index.js +0 -6
  107. package/src/state/index.ts +0 -8
  108. package/src/state/reducer.d.ts +0 -11
  109. package/src/state/reducer.d.ts.map +0 -1
  110. package/src/state/reducer.js +0 -443
  111. package/src/state/reducer.ts +0 -694
  112. package/src/state/types.d.ts +0 -162
  113. package/src/state/types.d.ts.map +0 -1
  114. package/src/state/types.js +0 -27
  115. package/src/state/types.ts +0 -160
  116. package/src/types/block.d.ts +0 -221
  117. package/src/types/block.d.ts.map +0 -1
  118. package/src/types/block.js +0 -6
  119. package/src/types/block.ts +0 -269
  120. package/src/types/index.d.ts +0 -8
  121. package/src/types/index.d.ts.map +0 -1
  122. package/src/types/index.js +0 -5
  123. package/src/types/index.ts +0 -17
  124. package/src/types/post.d.ts +0 -136
  125. package/src/types/post.d.ts.map +0 -1
  126. package/src/types/post.js +0 -5
  127. package/src/types/post.ts +0 -169
  128. package/src/utils/client.d.ts +0 -48
  129. package/src/utils/client.d.ts.map +0 -1
  130. package/src/utils/client.js +0 -77
  131. package/src/utils/client.ts +0 -122
  132. package/src/utils/index.ts +0 -7
  133. package/src/views/CanvasEditor/BlockWrapper.d.ts +0 -16
  134. package/src/views/CanvasEditor/BlockWrapper.d.ts.map +0 -1
  135. package/src/views/CanvasEditor/BlockWrapper.js +0 -276
  136. package/src/views/CanvasEditor/BlockWrapper.tsx +0 -522
  137. package/src/views/CanvasEditor/CanvasEditorView.d.ts +0 -14
  138. package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +0 -1
  139. package/src/views/CanvasEditor/CanvasEditorView.js +0 -209
  140. package/src/views/CanvasEditor/CanvasEditorView.tsx +0 -337
  141. package/src/views/CanvasEditor/EditorBody.d.ts +0 -22
  142. package/src/views/CanvasEditor/EditorBody.d.ts.map +0 -1
  143. package/src/views/CanvasEditor/EditorBody.js +0 -505
  144. package/src/views/CanvasEditor/EditorBody.tsx +0 -665
  145. package/src/views/CanvasEditor/EditorHeader.d.ts +0 -18
  146. package/src/views/CanvasEditor/EditorHeader.d.ts.map +0 -1
  147. package/src/views/CanvasEditor/EditorHeader.js +0 -101
  148. package/src/views/CanvasEditor/EditorHeader.tsx +0 -268
  149. package/src/views/CanvasEditor/LayoutContainer.d.ts +0 -17
  150. package/src/views/CanvasEditor/LayoutContainer.d.ts.map +0 -1
  151. package/src/views/CanvasEditor/LayoutContainer.js +0 -222
  152. package/src/views/CanvasEditor/LayoutContainer.tsx +0 -322
  153. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +0 -13
  154. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +0 -1
  155. package/src/views/CanvasEditor/SaveConfirmationModal.js +0 -78
  156. package/src/views/CanvasEditor/SaveConfirmationModal.tsx +0 -233
  157. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +0 -14
  158. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +0 -1
  159. package/src/views/CanvasEditor/components/CustomBlockItem.js +0 -44
  160. package/src/views/CanvasEditor/components/CustomBlockItem.tsx +0 -92
  161. package/src/views/CanvasEditor/components/EditorCanvas.d.ts +0 -29
  162. package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +0 -1
  163. package/src/views/CanvasEditor/components/EditorCanvas.js +0 -32
  164. package/src/views/CanvasEditor/components/EditorCanvas.tsx +0 -160
  165. package/src/views/CanvasEditor/components/EditorLibrary.d.ts +0 -7
  166. package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +0 -1
  167. package/src/views/CanvasEditor/components/EditorLibrary.js +0 -25
  168. package/src/views/CanvasEditor/components/EditorLibrary.tsx +0 -122
  169. package/src/views/CanvasEditor/components/EditorSidebar.d.ts +0 -13
  170. package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +0 -1
  171. package/src/views/CanvasEditor/components/EditorSidebar.js +0 -20
  172. package/src/views/CanvasEditor/components/EditorSidebar.tsx +0 -181
  173. package/src/views/CanvasEditor/components/ErrorBanner.d.ts +0 -6
  174. package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +0 -1
  175. package/src/views/CanvasEditor/components/ErrorBanner.js +0 -8
  176. package/src/views/CanvasEditor/components/ErrorBanner.tsx +0 -31
  177. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -25
  178. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +0 -1
  179. package/src/views/CanvasEditor/components/FeaturedMediaSection.js +0 -182
  180. package/src/views/CanvasEditor/components/FeaturedMediaSection.tsx +0 -341
  181. package/src/views/CanvasEditor/components/LibraryItem.d.ts +0 -14
  182. package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +0 -1
  183. package/src/views/CanvasEditor/components/LibraryItem.js +0 -43
  184. package/src/views/CanvasEditor/components/LibraryItem.tsx +0 -80
  185. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -15
  186. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +0 -1
  187. package/src/views/CanvasEditor/components/PrivacySettingsSection.js +0 -63
  188. package/src/views/CanvasEditor/components/PrivacySettingsSection.tsx +0 -212
  189. package/src/views/CanvasEditor/components/index.d.ts +0 -21
  190. package/src/views/CanvasEditor/components/index.d.ts.map +0 -1
  191. package/src/views/CanvasEditor/components/index.js +0 -12
  192. package/src/views/CanvasEditor/components/index.ts +0 -28
  193. package/src/views/CanvasEditor/hooks/index.d.ts +0 -10
  194. package/src/views/CanvasEditor/hooks/index.d.ts.map +0 -1
  195. package/src/views/CanvasEditor/hooks/index.js +0 -9
  196. package/src/views/CanvasEditor/hooks/index.ts +0 -10
  197. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +0 -8
  198. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +0 -1
  199. package/src/views/CanvasEditor/hooks/useHeroBlock.js +0 -79
  200. package/src/views/CanvasEditor/hooks/useHeroBlock.ts +0 -103
  201. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +0 -3
  202. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  203. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.js +0 -114
  204. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.ts +0 -142
  205. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +0 -5
  206. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +0 -1
  207. package/src/views/CanvasEditor/hooks/usePostLoader.js +0 -32
  208. package/src/views/CanvasEditor/hooks/usePostLoader.ts +0 -39
  209. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +0 -2
  210. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +0 -1
  211. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.js +0 -47
  212. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.ts +0 -55
  213. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +0 -25
  214. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +0 -1
  215. package/src/views/CanvasEditor/hooks/useUnsavedChanges.js +0 -285
  216. package/src/views/CanvasEditor/hooks/useUnsavedChanges.ts +0 -339
  217. package/src/views/CanvasEditor/index.d.ts +0 -16
  218. package/src/views/CanvasEditor/index.d.ts.map +0 -1
  219. package/src/views/CanvasEditor/index.js +0 -9
  220. package/src/views/CanvasEditor/index.ts +0 -16
  221. package/src/views/PostManager/EmptyState.d.ts +0 -10
  222. package/src/views/PostManager/EmptyState.d.ts.map +0 -1
  223. package/src/views/PostManager/EmptyState.js +0 -12
  224. package/src/views/PostManager/EmptyState.tsx +0 -42
  225. package/src/views/PostManager/PostActionsMenu.d.ts +0 -12
  226. package/src/views/PostManager/PostActionsMenu.d.ts.map +0 -1
  227. package/src/views/PostManager/PostActionsMenu.js +0 -58
  228. package/src/views/PostManager/PostActionsMenu.tsx +0 -112
  229. package/src/views/PostManager/PostCards.d.ts +0 -15
  230. package/src/views/PostManager/PostCards.d.ts.map +0 -1
  231. package/src/views/PostManager/PostCards.js +0 -79
  232. package/src/views/PostManager/PostCards.tsx +0 -197
  233. package/src/views/PostManager/PostFilters.d.ts +0 -16
  234. package/src/views/PostManager/PostFilters.d.ts.map +0 -1
  235. package/src/views/PostManager/PostFilters.js +0 -10
  236. package/src/views/PostManager/PostFilters.tsx +0 -95
  237. package/src/views/PostManager/PostManagerView.d.ts +0 -11
  238. package/src/views/PostManager/PostManagerView.d.ts.map +0 -1
  239. package/src/views/PostManager/PostManagerView.js +0 -174
  240. package/src/views/PostManager/PostManagerView.tsx +0 -289
  241. package/src/views/PostManager/PostStats.d.ts +0 -11
  242. package/src/views/PostManager/PostStats.d.ts.map +0 -1
  243. package/src/views/PostManager/PostStats.js +0 -46
  244. package/src/views/PostManager/PostStats.tsx +0 -81
  245. package/src/views/PostManager/PostTable.d.ts +0 -15
  246. package/src/views/PostManager/PostTable.d.ts.map +0 -1
  247. package/src/views/PostManager/PostTable.js +0 -79
  248. package/src/views/PostManager/PostTable.tsx +0 -230
  249. package/src/views/PostManager/index.d.ts +0 -12
  250. package/src/views/PostManager/index.d.ts.map +0 -1
  251. package/src/views/PostManager/index.js +0 -11
  252. package/src/views/PostManager/index.ts +0 -15
  253. package/src/views/Preview/PreviewBridgeView.d.ts +0 -12
  254. package/src/views/Preview/PreviewBridgeView.d.ts.map +0 -1
  255. package/src/views/Preview/PreviewBridgeView.js +0 -11
  256. package/src/views/Preview/PreviewBridgeView.tsx +0 -64
  257. package/src/views/Preview/index.d.ts +0 -6
  258. package/src/views/Preview/index.d.ts.map +0 -1
  259. package/src/views/Preview/index.js +0 -4
  260. package/src/views/Preview/index.ts +0 -7
  261. package/src/views/Settings/SettingsView.d.ts +0 -10
  262. package/src/views/Settings/SettingsView.d.ts.map +0 -1
  263. package/src/views/Settings/SettingsView.js +0 -111
  264. package/src/views/Settings/SettingsView.tsx +0 -298
  265. package/src/views/Settings/index.d.ts +0 -6
  266. package/src/views/Settings/index.d.ts.map +0 -1
  267. package/src/views/Settings/index.js +0 -4
  268. package/src/views/Settings/index.ts +0 -7
  269. package/src/views/SlugSEO/SlugSEOManagerView.d.ts +0 -12
  270. package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +0 -1
  271. package/src/views/SlugSEO/SlugSEOManagerView.js +0 -11
  272. package/src/views/SlugSEO/SlugSEOManagerView.tsx +0 -94
  273. package/src/views/SlugSEO/index.d.ts +0 -6
  274. package/src/views/SlugSEO/index.d.ts.map +0 -1
  275. package/src/views/SlugSEO/index.js +0 -4
  276. package/src/views/SlugSEO/index.ts +0 -7
package/src/index.tsx DELETED
@@ -1,335 +0,0 @@
1
- /**
2
- * Plugin Blog - Main Entry Point
3
- * Block-Based Blog Management System
4
- * Multi-Tenant Architecture: Accepts custom blocks from client applications
5
- */
6
-
7
- 'use client';
8
-
9
- import React, { useMemo, useEffect } from 'react';
10
- import { EditorProvider } from './state/EditorContext';
11
- import { ClientBlockDefinition } from './types/block';
12
- import { PostManagerView } from './views/PostManager';
13
- import { CanvasEditorView } from './views/CanvasEditor';
14
- import { editorStateToAPI } from './lib/mappers/apiMapper';
15
- import { SlugSEOManagerView } from './views/SlugSEO';
16
- import { PreviewBridgeView } from './views/Preview';
17
- import { SettingsView } from './views/Settings';
18
- import { useHeroBlockValidation, findHeroBlock } from './lib/utils/configValidation';
19
-
20
- /**
21
- * Plugin Props Interface
22
- * Matches the PluginProps from @jhits/jhits-dashboard
23
- */
24
- export interface PluginProps {
25
- subPath: string[];
26
- siteId: string;
27
- locale: string;
28
- /** Custom blocks from client application (optional, can also come from window.__JHITS_PLUGIN_PROPS__) */
29
- customBlocks?: ClientBlockDefinition[];
30
- /** Enable dark mode for content area and wrappers (default: true) */
31
- darkMode?: boolean;
32
- /** Background colors for the editor */
33
- backgroundColors?: {
34
- /** Background color for light mode (REQUIRED) */
35
- light: string;
36
- /** Background color for dark mode (optional) */
37
- dark?: string;
38
- };
39
- }
40
-
41
- /**
42
- * Main Router Component
43
- * Handles routing within the blog plugin
44
- *
45
- * Client Handshake:
46
- * - Client apps can pass customBlocks via props
47
- * - Or via window.__JHITS_PLUGIN_PROPS__['plugin-blog'].customBlocks
48
- * - The EditorProvider will automatically register these blocks
49
- */
50
- export default function BlogPlugin(props: PluginProps) {
51
- const { subPath, siteId, locale, customBlocks: propsCustomBlocks, darkMode: propsDarkMode, backgroundColors: propsBackgroundColors } = props;
52
-
53
- // Get custom blocks from props or window global (client app injection point)
54
- const customBlocks = useMemo(() => {
55
- // First, try props
56
- if (propsCustomBlocks && propsCustomBlocks.length > 0) {
57
- return propsCustomBlocks;
58
- }
59
-
60
- // Fallback to window global (for client app injection)
61
- if (typeof window !== 'undefined' && (window as any).__JHITS_PLUGIN_PROPS__) {
62
- const pluginProps = (window as any).__JHITS_PLUGIN_PROPS__['plugin-blog'];
63
- if (pluginProps?.customBlocks) {
64
- return pluginProps.customBlocks as ClientBlockDefinition[];
65
- }
66
- }
67
-
68
- return [];
69
- }, [propsCustomBlocks]);
70
-
71
- // Get dark mode setting from props, localStorage (dev settings), or window global
72
- // Priority: localStorage (dev) > props > window global > default
73
- const darkMode = useMemo(() => {
74
- // First, check localStorage for dev settings (highest priority for dev)
75
- if (typeof window !== 'undefined') {
76
- try {
77
- const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
78
- if (saved) {
79
- const config = JSON.parse(saved);
80
- if (config.darkMode !== undefined) {
81
- return config.darkMode as boolean;
82
- }
83
- }
84
- } catch (e) {
85
- // Ignore localStorage errors
86
- }
87
- }
88
-
89
- // Then try props
90
- if (propsDarkMode !== undefined) {
91
- return propsDarkMode;
92
- }
93
-
94
- // Fallback to window global if prop not provided
95
- if (typeof window !== 'undefined' && (window as any).__JHITS_PLUGIN_PROPS__) {
96
- const pluginProps = (window as any).__JHITS_PLUGIN_PROPS__['plugin-blog'];
97
- if (pluginProps?.darkMode !== undefined) {
98
- return pluginProps.darkMode as boolean;
99
- }
100
- }
101
-
102
- return true; // Default to dark mode enabled
103
- }, [propsDarkMode]);
104
-
105
- // Get background colors from props, localStorage (dev settings), or window global
106
- // Priority: localStorage (dev) > props > window global
107
- const backgroundColors = useMemo(() => {
108
- // First, check localStorage for dev settings (highest priority for dev)
109
- if (typeof window !== 'undefined') {
110
- try {
111
- const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
112
- if (saved) {
113
- const config = JSON.parse(saved);
114
- if (config.backgroundColors) {
115
- return config.backgroundColors;
116
- }
117
- }
118
- } catch (e) {
119
- // Ignore localStorage errors
120
- }
121
- }
122
-
123
- // Then try props
124
- if (propsBackgroundColors) {
125
- return propsBackgroundColors;
126
- }
127
-
128
- // Fallback to window global
129
- if (typeof window !== 'undefined' && (window as any).__JHITS_PLUGIN_PROPS__) {
130
- const pluginProps = (window as any).__JHITS_PLUGIN_PROPS__['plugin-blog'];
131
- if (pluginProps?.backgroundColors) {
132
- return pluginProps.backgroundColors as { light: string; dark?: string };
133
- }
134
- }
135
-
136
- return undefined;
137
- }, [propsBackgroundColors]);
138
-
139
- const route = subPath[0] || 'posts';
140
-
141
- // Validate hero block configuration (only checks when needed)
142
- useHeroBlockValidation(route, customBlocks, propsCustomBlocks);
143
-
144
- // Get hero block definition for logging/debugging (only for routes that need it)
145
- const heroBlockDefinition = useMemo(() => {
146
- const needsHeroBlock = route === 'editor' || route === 'new' || route === 'preview';
147
- return needsHeroBlock ? findHeroBlock(customBlocks) : undefined;
148
- }, [customBlocks, route]);
149
-
150
- // Listen for config updates from settings screen
151
- useEffect(() => {
152
- if (typeof window === 'undefined') return;
153
-
154
- const handleConfigUpdate = () => {
155
- // Reload page to apply changes (simplest way to ensure all components pick up new values)
156
- window.location.reload();
157
- };
158
-
159
- window.addEventListener('blog-plugin-config-updated', handleConfigUpdate as EventListener);
160
- return () => {
161
- window.removeEventListener('blog-plugin-config-updated', handleConfigUpdate as EventListener);
162
- };
163
- }, []);
164
-
165
- if (heroBlockDefinition !== undefined) {
166
- console.log('[BlogPlugin] Hero block definition:', heroBlockDefinition ? 'found' : 'not found (REQUIRED)');
167
- }
168
-
169
- // Route to appropriate view
170
- switch (route) {
171
- case 'posts':
172
- return <PostManagerView siteId={siteId} locale={locale} />;
173
-
174
- case 'editor':
175
- const postId = subPath[1]; // This is actually the slug, not the ID
176
- return (
177
- <EditorProvider
178
- customBlocks={customBlocks}
179
- darkMode={darkMode}
180
- backgroundColors={backgroundColors}
181
- onSave={async (state, heroBlock) => {
182
- // Save to API - update existing post
183
- // Use the route postId (original slug) to identify which blog to update
184
- // If route postId is missing, use state.slug or state.postId as fallback
185
- const originalSlug = postId || state.slug || state.postId;
186
- if (!originalSlug) {
187
- throw new Error('Cannot save: no post identifier available. Please reload the page.');
188
- }
189
- console.log('[BlogPlugin] Saving post with slug:', originalSlug);
190
- const apiData = editorStateToAPI(state, undefined, heroBlock);
191
- const response = await fetch(`/api/plugin-blog/${originalSlug}`, {
192
- method: 'PUT',
193
- headers: { 'Content-Type': 'application/json' },
194
- credentials: 'include', // Include cookies for authentication
195
- body: JSON.stringify(apiData),
196
- });
197
- if (!response.ok) {
198
- const error = await response.json();
199
- console.error('[BlogPlugin] Save failed:', {
200
- status: response.status,
201
- statusText: response.statusText,
202
- error,
203
- missingFields: error.missingFields,
204
- });
205
- // Provide more detailed error message if available
206
- const errorMessage = error.message || error.error || 'Failed to save post';
207
- const missingFieldsMsg = error.missingFields && error.missingFields.length > 0
208
- ? ` Missing: ${error.missingFields.join(', ')}`
209
- : '';
210
- throw new Error(errorMessage + missingFieldsMsg);
211
- }
212
- const result = await response.json();
213
- // If the slug changed, update the URL
214
- if (result.slug && result.slug !== originalSlug) {
215
- window.history.replaceState(null, '', `/dashboard/blog/editor/${result.slug}`);
216
- }
217
- return result;
218
- }}
219
- >
220
- <CanvasEditorView postId={postId} siteId={siteId} locale={locale} darkMode={darkMode} backgroundColors={backgroundColors} />
221
- </EditorProvider>
222
- );
223
-
224
- case 'new':
225
- return (
226
- <EditorProvider
227
- customBlocks={customBlocks}
228
- darkMode={darkMode}
229
- backgroundColors={backgroundColors}
230
- onSave={async (state) => {
231
- // Save to API - create new post
232
- const apiData = editorStateToAPI(state);
233
- const response = await fetch('/api/plugin-blog/new', {
234
- method: 'POST',
235
- headers: { 'Content-Type': 'application/json' },
236
- credentials: 'include', // Include cookies for authentication
237
- body: JSON.stringify(apiData),
238
- });
239
- if (!response.ok) {
240
- const error = await response.json();
241
- throw new Error(error.message || 'Failed to create post');
242
- }
243
- const result = await response.json();
244
- // Update the URL to the new post's slug
245
- if (result.slug) {
246
- window.history.replaceState(null, '', `/dashboard/blog/editor/${result.slug}`);
247
- }
248
- return result;
249
- }}
250
- >
251
- <CanvasEditorView siteId={siteId} locale={locale} darkMode={darkMode} backgroundColors={backgroundColors} />
252
- </EditorProvider>
253
- );
254
-
255
- case 'seo':
256
- const seoPostId = subPath[1];
257
- return <SlugSEOManagerView postId={seoPostId} siteId={siteId} locale={locale} />;
258
-
259
- case 'preview':
260
- const previewPostId = subPath[1];
261
- return <PreviewBridgeView postId={previewPostId} siteId={siteId} locale={locale} />;
262
-
263
- case 'settings':
264
- case 'install':
265
- return <SettingsView siteId={siteId} locale={locale} />;
266
-
267
- default:
268
- return <PostManagerView siteId={siteId} locale={locale} />;
269
- }
270
- }
271
-
272
-
273
- // Export for use as default
274
- export { BlogPlugin as Index };
275
-
276
- // Export types for client applications
277
- export type {
278
- Block,
279
- BlockTypeDefinition,
280
- ClientBlockDefinition,
281
- RichTextFormattingConfig,
282
- BlockEditProps,
283
- BlockPreviewProps,
284
- IBlockComponent,
285
- } from './types';
286
-
287
- // Export post types
288
- export type {
289
- SEOMetadata,
290
- PublicationData,
291
- PostStatus,
292
- PostMetadata,
293
- BlogPost,
294
- PostListItem,
295
- PostFilterOptions,
296
- } from './types/post';
297
-
298
- // Export initialization utility for easy setup
299
- export { initBlogPlugin } from './init';
300
- export type { BlogPluginConfig } from './init';
301
-
302
- // Export rich text components for client applications
303
- export { RichTextEditor, RichTextPreview } from './lib/rich-text';
304
- export type { RichTextEditorProps, RichTextPreviewProps } from './lib/rich-text';
305
-
306
- // Export hooks for client applications
307
- export { useBlogs, useBlog } from './hooks';
308
- export type { UseBlogsOptions, UseBlogsResult, UseBlogOptions, UseBlogResult } from './hooks';
309
-
310
- // Export client utilities
311
- export { fetchBlogs, fetchBlog } from './utils/client';
312
- export type { FetchBlogsOptions, FetchBlogsResult, FetchBlogOptions } from './utils/client';
313
-
314
- // Export block rendering components
315
- export { BlockRenderer, BlocksRenderer } from './lib/blocks/BlockRenderer';
316
-
317
- // Export block registry
318
- export { blockRegistry } from './registry';
319
-
320
- // Export layout block registration
321
- export { registerLayoutBlocks } from './lib/layouts/registerLayoutBlocks';
322
-
323
- // Export config storage utilities
324
- export { getPluginConfig, savePluginConfig } from './lib/config-storage';
325
-
326
- // Export editor state management
327
- export { EditorProvider, useEditor } from './state/EditorContext';
328
- export type { EditorProviderProps, EditorState, EditorContextValue } from './state';
329
-
330
- // Export hooks
331
- export { useCategories } from './hooks/useCategories';
332
-
333
- // Note: API handlers are server-only and exported from ./index.ts (server entry point)
334
- // They are NOT exported here to prevent client/server context mixing
335
-
package/src/init.d.ts DELETED
@@ -1,40 +0,0 @@
1
- /**
2
- * Blog Plugin Initialization Utility
3
- *
4
- * Simple function to initialize the blog plugin with client configuration.
5
- * Call this once in your app (e.g., in a script tag or root layout) to configure
6
- * the blog plugin without needing a React component.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { initBlogPlugin } from '@jhits/plugin-blog/init';
11
- * import { blogConfig } from '@/plugins/blog-config';
12
- *
13
- * // Call once when your app loads
14
- * initBlogPlugin(blogConfig);
15
- * ```
16
- */
17
- import type { ClientBlockDefinition } from './types/block';
18
- export interface BlogPluginConfig {
19
- /** Custom blocks available in the editor */
20
- customBlocks?: ClientBlockDefinition[];
21
- /** Dark mode setting for the editor content area and wrappers (default: true) */
22
- darkMode?: boolean;
23
- /** Background colors for the editor */
24
- backgroundColors?: {
25
- /** Background color for light mode (REQUIRED) - CSS color value (hex, rgb, or named color) */
26
- light: string;
27
- /** Background color for dark mode (optional) - CSS color value (hex, rgb, or named color) */
28
- dark?: string;
29
- };
30
- }
31
- /**
32
- * Initialize the blog plugin with client configuration
33
- *
34
- * This function sets up the window global that the plugin reads from automatically.
35
- * Call this once when your app loads, before the plugin is rendered.
36
- *
37
- * @param config - Blog plugin configuration (customBlocks, darkMode, etc.)
38
- */
39
- export declare function initBlogPlugin(config: BlogPluginConfig): void;
40
- //# sourceMappingURL=init.d.ts.map
package/src/init.d.ts.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["init.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAE3D,MAAM,WAAW,gBAAgB;IAC7B,4CAA4C;IAC5C,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,8FAA8F;QAC9F,KAAK,EAAE,MAAM,CAAC;QACd,6FAA6F;QAC7F,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAiB7D"}
package/src/init.js DELETED
@@ -1,41 +0,0 @@
1
- /**
2
- * Blog Plugin Initialization Utility
3
- *
4
- * Simple function to initialize the blog plugin with client configuration.
5
- * Call this once in your app (e.g., in a script tag or root layout) to configure
6
- * the blog plugin without needing a React component.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { initBlogPlugin } from '@jhits/plugin-blog/init';
11
- * import { blogConfig } from '@/plugins/blog-config';
12
- *
13
- * // Call once when your app loads
14
- * initBlogPlugin(blogConfig);
15
- * ```
16
- */
17
- 'use client';
18
- /**
19
- * Initialize the blog plugin with client configuration
20
- *
21
- * This function sets up the window global that the plugin reads from automatically.
22
- * Call this once when your app loads, before the plugin is rendered.
23
- *
24
- * @param config - Blog plugin configuration (customBlocks, darkMode, etc.)
25
- */
26
- export function initBlogPlugin(config) {
27
- if (typeof window === 'undefined') {
28
- // Server-side: no-op
29
- return;
30
- }
31
- // Initialize the global plugin props object if it doesn't exist
32
- if (!window.__JHITS_PLUGIN_PROPS__) {
33
- window.__JHITS_PLUGIN_PROPS__ = {};
34
- }
35
- // Set blog plugin configuration
36
- window.__JHITS_PLUGIN_PROPS__['plugin-blog'] = {
37
- customBlocks: config.customBlocks || [],
38
- darkMode: config.darkMode !== undefined ? config.darkMode : true, // Default to true
39
- backgroundColors: config.backgroundColors || undefined,
40
- };
41
- }
package/src/init.tsx DELETED
@@ -1,63 +0,0 @@
1
- /**
2
- * Blog Plugin Initialization Utility
3
- *
4
- * Simple function to initialize the blog plugin with client configuration.
5
- * Call this once in your app (e.g., in a script tag or root layout) to configure
6
- * the blog plugin without needing a React component.
7
- *
8
- * @example
9
- * ```typescript
10
- * import { initBlogPlugin } from '@jhits/plugin-blog/init';
11
- * import { blogConfig } from '@/plugins/blog-config';
12
- *
13
- * // Call once when your app loads
14
- * initBlogPlugin(blogConfig);
15
- * ```
16
- */
17
-
18
- 'use client';
19
-
20
- import React from 'react';
21
- import type { ClientBlockDefinition } from './types/block';
22
-
23
- export interface BlogPluginConfig {
24
- /** Custom blocks available in the editor */
25
- customBlocks?: ClientBlockDefinition[];
26
- /** Dark mode setting for the editor content area and wrappers (default: true) */
27
- darkMode?: boolean;
28
- /** Background colors for the editor */
29
- backgroundColors?: {
30
- /** Background color for light mode (REQUIRED) - CSS color value (hex, rgb, or named color) */
31
- light: string;
32
- /** Background color for dark mode (optional) - CSS color value (hex, rgb, or named color) */
33
- dark?: string;
34
- };
35
- }
36
-
37
- /**
38
- * Initialize the blog plugin with client configuration
39
- *
40
- * This function sets up the window global that the plugin reads from automatically.
41
- * Call this once when your app loads, before the plugin is rendered.
42
- *
43
- * @param config - Blog plugin configuration (customBlocks, darkMode, etc.)
44
- */
45
- export function initBlogPlugin(config: BlogPluginConfig): void {
46
- if (typeof window === 'undefined') {
47
- // Server-side: no-op
48
- return;
49
- }
50
-
51
- // Initialize the global plugin props object if it doesn't exist
52
- if (!(window as any).__JHITS_PLUGIN_PROPS__) {
53
- (window as any).__JHITS_PLUGIN_PROPS__ = {};
54
- }
55
-
56
- // Set blog plugin configuration
57
- (window as any).__JHITS_PLUGIN_PROPS__['plugin-blog'] = {
58
- customBlocks: config.customBlocks || [],
59
- darkMode: config.darkMode !== undefined ? config.darkMode : true, // Default to true
60
- backgroundColors: config.backgroundColors || undefined,
61
- };
62
- }
63
-
@@ -1,54 +0,0 @@
1
- /**
2
- * Block Renderer
3
- * Library component for rendering blocks (decoupled from editor)
4
- * This is the "headless" rendering layer
5
- *
6
- * Multi-Tenant: Uses Preview components from client-provided blocks
7
- */
8
- import React from 'react';
9
- import { Block, BlockPreviewProps } from '../../types/block';
10
- /**
11
- * Block Renderer Props
12
- */
13
- export interface BlockRendererProps {
14
- /** Block to render */
15
- block: Block;
16
- /** Custom renderers for specific block types (optional override) */
17
- customRenderers?: Map<string, React.ComponentType<BlockPreviewProps>>;
18
- /** Additional context for rendering */
19
- context?: {
20
- siteId?: string;
21
- locale?: string;
22
- [key: string]: unknown;
23
- };
24
- }
25
- /**
26
- * Block Renderer Component
27
- * Renders a single block using its Preview component from the registry
28
- *
29
- * This is the headless rendering layer - it uses the Preview component
30
- * provided by the client application, allowing each client to have
31
- * their own design system in the frontend while the editor uses
32
- * the dashboard's design system.
33
- */
34
- export declare function BlockRenderer({ block, customRenderers, context }: BlockRendererProps): import("react/jsx-runtime").JSX.Element;
35
- /**
36
- * Blocks Renderer
37
- * Renders an array of blocks
38
- */
39
- export interface BlocksRendererProps {
40
- /** Array of blocks to render */
41
- blocks: Block[];
42
- /** Custom renderers for specific block types */
43
- customRenderers?: Map<string, React.ComponentType<{
44
- block: Block;
45
- }>>;
46
- /** Additional props to pass to renderers */
47
- renderProps?: Record<string, unknown>;
48
- /** Wrapper component for the blocks */
49
- wrapper?: React.ComponentType<{
50
- children: React.ReactNode;
51
- }>;
52
- }
53
- export declare function BlocksRenderer({ blocks, customRenderers, renderProps, wrapper: Wrapper, }: BlocksRendererProps): import("react/jsx-runtime").JSX.Element;
54
- //# sourceMappingURL=BlockRenderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"BlockRenderer.d.ts","sourceRoot":"","sources":["BlockRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAI7D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,sBAAsB;IACtB,KAAK,EAAE,KAAK,CAAC;IAEb,oEAAoE;IACpE,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAEtE,uCAAuC;IACvC,OAAO,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KAC1B,CAAC;CACL;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,EAC1B,KAAK,EACL,eAAe,EACf,OAAY,EACf,EAAE,kBAAkB,2CAqDpB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,gCAAgC;IAChC,MAAM,EAAE,KAAK,EAAE,CAAC;IAEhB,gDAAgD;IAChD,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC,CAAC,CAAC;IAErE,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEtC,uCAAuC;IACvC,OAAO,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;CAChE;AAED,wBAAgB,cAAc,CAAC,EAC3B,MAAM,EACN,eAAe,EACf,WAAW,EACX,OAAO,EAAE,OAAO,GACnB,EAAE,mBAAmB,2CAerB"}
@@ -1,54 +0,0 @@
1
- /**
2
- * Block Renderer
3
- * Library component for rendering blocks (decoupled from editor)
4
- * This is the "headless" rendering layer
5
- *
6
- * Multi-Tenant: Uses Preview components from client-provided blocks
7
- */
8
- 'use client';
9
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
10
- import { blockRegistry } from '../../registry/BlockRegistry';
11
- /**
12
- * Block Renderer Component
13
- * Renders a single block using its Preview component from the registry
14
- *
15
- * This is the headless rendering layer - it uses the Preview component
16
- * provided by the client application, allowing each client to have
17
- * their own design system in the frontend while the editor uses
18
- * the dashboard's design system.
19
- */
20
- export function BlockRenderer({ block, customRenderers, context = {} }) {
21
- // Check for custom renderer override first
22
- if (customRenderers === null || customRenderers === void 0 ? void 0 : customRenderers.has(block.type)) {
23
- const CustomRenderer = customRenderers.get(block.type);
24
- return _jsx(CustomRenderer, { block: block, context: context });
25
- }
26
- // Get block definition from registry
27
- const definition = blockRegistry.get(block.type);
28
- if (!definition) {
29
- console.warn(`Block type "${block.type}" not found in registry. Available types:`, blockRegistry.getAll().map(b => b.type).join(', '));
30
- return (_jsxs("div", { className: "p-4 border border-red-300 bg-red-50 rounded", children: [_jsxs("p", { className: "text-red-600", children: ["Unknown block type: ", block.type] }), _jsx("p", { className: "text-xs text-red-500 mt-1", children: "Make sure this block type is registered via customBlocks prop" })] }));
31
- }
32
- // Use the Preview component from the block definition
33
- // This is provided by the client application
34
- const PreviewComponent = definition.components.Preview;
35
- // Check if this is a container block with children
36
- const isContainer = definition.isContainer === true;
37
- const childBlocks = isContainer && block.children && Array.isArray(block.children) && block.children.length > 0
38
- ? (typeof block.children[0] === 'object'
39
- ? block.children
40
- : [])
41
- : [];
42
- // If container block, pass child blocks and render function
43
- if (isContainer) {
44
- return (_jsx(PreviewComponent, { block: block, context: context, childBlocks: childBlocks, renderChild: (childBlock) => (_jsx(BlockRenderer, { block: childBlock, customRenderers: customRenderers, context: context })) }));
45
- }
46
- return _jsx(PreviewComponent, { block: block, context: context });
47
- }
48
- export function BlocksRenderer({ blocks, customRenderers, renderProps, wrapper: Wrapper, }) {
49
- const content = blocks.map((block, index) => (_jsx(BlockRenderer, { block: block, customRenderers: customRenderers, context: renderProps }, block.id || index)));
50
- if (Wrapper) {
51
- return _jsx(Wrapper, { children: content });
52
- }
53
- return _jsx(_Fragment, { children: content });
54
- }