@jhits/plugin-blog 0.0.7 → 0.0.9

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 (440) hide show
  1. package/dist/api/categories.d.ts +8 -0
  2. package/dist/api/categories.d.ts.map +1 -0
  3. package/dist/api/categories.js +30 -0
  4. package/dist/api/check-title.d.ts +8 -0
  5. package/dist/api/check-title.d.ts.map +1 -0
  6. package/dist/api/check-title.js +47 -0
  7. package/dist/api/config-handler.d.ts +21 -0
  8. package/dist/api/config-handler.d.ts.map +1 -0
  9. package/dist/api/config-handler.js +46 -0
  10. package/dist/api/handler.d.ts +42 -0
  11. package/dist/api/handler.d.ts.map +1 -0
  12. package/dist/api/handler.js +331 -0
  13. package/dist/api/index.d.ts +12 -0
  14. package/dist/api/index.d.ts.map +1 -0
  15. package/dist/api/index.js +12 -0
  16. package/dist/api/route.d.ts +50 -0
  17. package/dist/api/route.d.ts.map +1 -0
  18. package/dist/api/route.js +69 -0
  19. package/dist/api/router.d.ts +27 -0
  20. package/dist/api/router.d.ts.map +1 -0
  21. package/dist/api/router.js +98 -0
  22. package/dist/api-server.d.ts +9 -0
  23. package/dist/api-server.d.ts.map +1 -0
  24. package/dist/api-server.js +9 -0
  25. package/dist/config.d.ts +14 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +156 -0
  28. package/dist/hooks/index.d.ts +8 -0
  29. package/dist/hooks/index.d.ts.map +1 -0
  30. package/dist/hooks/index.js +7 -0
  31. package/dist/hooks/useBlog.d.ts +31 -0
  32. package/dist/hooks/useBlog.d.ts.map +1 -0
  33. package/dist/hooks/useBlog.js +57 -0
  34. package/dist/hooks/useBlogs.d.ts +39 -0
  35. package/dist/hooks/useBlogs.d.ts.map +1 -0
  36. package/dist/hooks/useBlogs.js +82 -0
  37. package/dist/hooks/useCategories.d.ts +9 -0
  38. package/dist/hooks/useCategories.d.ts.map +1 -0
  39. package/dist/hooks/useCategories.js +70 -0
  40. package/dist/index.d.ts +55 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +228 -0
  43. package/dist/index.server.d.ts +12 -0
  44. package/dist/index.server.d.ts.map +1 -0
  45. package/dist/index.server.js +10 -0
  46. package/dist/init.d.ts +40 -0
  47. package/dist/init.d.ts.map +1 -0
  48. package/dist/init.js +41 -0
  49. package/dist/lib/blocks/BlockRenderer.d.ts +54 -0
  50. package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -0
  51. package/dist/lib/blocks/BlockRenderer.js +54 -0
  52. package/dist/lib/blocks/index.d.ts +5 -0
  53. package/dist/lib/blocks/index.d.ts.map +1 -0
  54. package/dist/lib/blocks/index.js +4 -0
  55. package/dist/lib/config-storage.d.ts +30 -0
  56. package/dist/lib/config-storage.d.ts.map +1 -0
  57. package/dist/lib/config-storage.js +31 -0
  58. package/dist/lib/index.d.ts +8 -0
  59. package/dist/lib/index.d.ts.map +1 -0
  60. package/dist/lib/index.js +7 -0
  61. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
  62. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
  63. package/dist/lib/layouts/blocks/ColumnsBlock.js +186 -0
  64. package/dist/lib/layouts/blocks/SectionBlock.d.ts +25 -0
  65. package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
  66. package/dist/lib/layouts/blocks/SectionBlock.js +44 -0
  67. package/dist/lib/layouts/blocks/index.d.ts +7 -0
  68. package/dist/lib/layouts/blocks/index.d.ts.map +1 -0
  69. package/dist/lib/layouts/blocks/index.js +6 -0
  70. package/dist/lib/layouts/index.d.ts +23 -0
  71. package/dist/lib/layouts/index.d.ts.map +1 -0
  72. package/dist/lib/layouts/index.js +45 -0
  73. package/dist/lib/layouts/registerLayoutBlocks.d.ts +9 -0
  74. package/dist/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
  75. package/dist/lib/layouts/registerLayoutBlocks.js +60 -0
  76. package/dist/lib/mappers/apiMapper.d.ts +66 -0
  77. package/dist/lib/mappers/apiMapper.d.ts.map +1 -0
  78. package/dist/lib/mappers/apiMapper.js +188 -0
  79. package/dist/lib/migration/index.d.ts +5 -0
  80. package/dist/lib/migration/index.d.ts.map +1 -0
  81. package/dist/lib/migration/index.js +4 -0
  82. package/dist/lib/migration/mapper.d.ts +37 -0
  83. package/dist/lib/migration/mapper.d.ts.map +1 -0
  84. package/dist/lib/migration/mapper.js +98 -0
  85. package/dist/lib/rich-text/RichTextEditor.d.ts +45 -0
  86. package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -0
  87. package/dist/lib/rich-text/RichTextEditor.js +556 -0
  88. package/dist/lib/rich-text/RichTextPreview.d.ts +16 -0
  89. package/dist/lib/rich-text/RichTextPreview.d.ts.map +1 -0
  90. package/dist/lib/rich-text/RichTextPreview.js +144 -0
  91. package/dist/lib/rich-text/index.d.ts +9 -0
  92. package/dist/lib/rich-text/index.d.ts.map +1 -0
  93. package/dist/lib/rich-text/index.js +6 -0
  94. package/dist/lib/utils/blockHelpers.d.ts +23 -0
  95. package/dist/lib/utils/blockHelpers.d.ts.map +1 -0
  96. package/dist/lib/utils/blockHelpers.js +65 -0
  97. package/dist/lib/utils/configValidation.d.ts +23 -0
  98. package/dist/lib/utils/configValidation.d.ts.map +1 -0
  99. package/dist/lib/utils/configValidation.js +111 -0
  100. package/dist/lib/utils/index.d.ts +7 -0
  101. package/dist/lib/utils/index.d.ts.map +1 -0
  102. package/dist/lib/utils/index.js +6 -0
  103. package/dist/lib/utils/slugify.d.ts +25 -0
  104. package/dist/lib/utils/slugify.d.ts.map +1 -0
  105. package/dist/lib/utils/slugify.js +65 -0
  106. package/dist/registry/BlockRegistry.d.ts +62 -0
  107. package/dist/registry/BlockRegistry.d.ts.map +1 -0
  108. package/dist/registry/BlockRegistry.js +112 -0
  109. package/dist/registry/index.d.ts +6 -0
  110. package/dist/registry/index.d.ts.map +1 -0
  111. package/dist/registry/index.js +4 -0
  112. package/dist/state/EditorContext.d.ts +45 -0
  113. package/dist/state/EditorContext.d.ts.map +1 -0
  114. package/dist/state/EditorContext.js +215 -0
  115. package/dist/state/index.d.ts +7 -0
  116. package/dist/state/index.d.ts.map +1 -0
  117. package/dist/state/index.js +6 -0
  118. package/dist/state/reducer.d.ts +11 -0
  119. package/dist/state/reducer.d.ts.map +1 -0
  120. package/dist/state/reducer.js +599 -0
  121. package/dist/state/types.d.ts +162 -0
  122. package/dist/state/types.d.ts.map +1 -0
  123. package/dist/state/types.js +27 -0
  124. package/dist/types/block.d.ts +221 -0
  125. package/dist/types/block.d.ts.map +1 -0
  126. package/dist/types/block.js +6 -0
  127. package/dist/types/index.d.ts +8 -0
  128. package/dist/types/index.d.ts.map +1 -0
  129. package/dist/types/index.js +5 -0
  130. package/dist/types/post.d.ts +136 -0
  131. package/dist/types/post.d.ts.map +1 -0
  132. package/dist/types/post.js +5 -0
  133. package/dist/utils/client.d.ts +48 -0
  134. package/dist/utils/client.d.ts.map +1 -0
  135. package/dist/utils/client.js +77 -0
  136. package/dist/utils/index.d.ts +6 -0
  137. package/dist/utils/index.d.ts.map +1 -0
  138. package/dist/utils/index.js +5 -0
  139. package/dist/views/CanvasEditor/BlockWrapper.d.ts +16 -0
  140. package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
  141. package/dist/views/CanvasEditor/BlockWrapper.js +285 -0
  142. package/dist/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
  143. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
  144. package/dist/views/CanvasEditor/CanvasEditorView.js +215 -0
  145. package/dist/views/CanvasEditor/EditorBody.d.ts +22 -0
  146. package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -0
  147. package/dist/views/CanvasEditor/EditorBody.js +505 -0
  148. package/dist/views/CanvasEditor/EditorHeader.d.ts +18 -0
  149. package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
  150. package/dist/views/CanvasEditor/EditorHeader.js +101 -0
  151. package/dist/views/CanvasEditor/LayoutContainer.d.ts +17 -0
  152. package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
  153. package/dist/views/CanvasEditor/LayoutContainer.js +222 -0
  154. package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
  155. package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
  156. package/dist/views/CanvasEditor/SaveConfirmationModal.js +78 -0
  157. package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
  158. package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
  159. package/dist/views/CanvasEditor/components/CustomBlockItem.js +44 -0
  160. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
  161. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
  162. package/dist/views/CanvasEditor/components/EditorCanvas.js +32 -0
  163. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
  164. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
  165. package/dist/views/CanvasEditor/components/EditorLibrary.js +25 -0
  166. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
  167. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
  168. package/dist/views/CanvasEditor/components/EditorSidebar.js +19 -0
  169. package/dist/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
  170. package/dist/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
  171. package/dist/views/CanvasEditor/components/ErrorBanner.js +8 -0
  172. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
  173. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
  174. package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +199 -0
  175. package/dist/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
  176. package/dist/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
  177. package/dist/views/CanvasEditor/components/LibraryItem.js +43 -0
  178. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
  179. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
  180. package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +70 -0
  181. package/dist/views/CanvasEditor/components/index.d.ts +21 -0
  182. package/dist/views/CanvasEditor/components/index.d.ts.map +1 -0
  183. package/dist/views/CanvasEditor/components/index.js +12 -0
  184. package/dist/views/CanvasEditor/hooks/index.d.ts +10 -0
  185. package/dist/views/CanvasEditor/hooks/index.d.ts.map +1 -0
  186. package/dist/views/CanvasEditor/hooks/index.js +9 -0
  187. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
  188. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
  189. package/dist/views/CanvasEditor/hooks/useHeroBlock.js +90 -0
  190. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
  191. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  192. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.js +119 -0
  193. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
  194. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
  195. package/dist/views/CanvasEditor/hooks/usePostLoader.js +32 -0
  196. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
  197. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
  198. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
  199. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
  200. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
  201. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
  202. package/dist/views/CanvasEditor/index.d.ts +16 -0
  203. package/dist/views/CanvasEditor/index.d.ts.map +1 -0
  204. package/dist/views/CanvasEditor/index.js +9 -0
  205. package/dist/views/PostManager/EmptyState.d.ts +10 -0
  206. package/dist/views/PostManager/EmptyState.d.ts.map +1 -0
  207. package/dist/views/PostManager/EmptyState.js +12 -0
  208. package/dist/views/PostManager/PostActionsMenu.d.ts +12 -0
  209. package/dist/views/PostManager/PostActionsMenu.d.ts.map +1 -0
  210. package/dist/views/PostManager/PostActionsMenu.js +58 -0
  211. package/dist/views/PostManager/PostCards.d.ts +15 -0
  212. package/dist/views/PostManager/PostCards.d.ts.map +1 -0
  213. package/dist/views/PostManager/PostCards.js +77 -0
  214. package/dist/views/PostManager/PostFilters.d.ts +16 -0
  215. package/dist/views/PostManager/PostFilters.d.ts.map +1 -0
  216. package/dist/views/PostManager/PostFilters.js +10 -0
  217. package/dist/views/PostManager/PostManagerView.d.ts +11 -0
  218. package/dist/views/PostManager/PostManagerView.d.ts.map +1 -0
  219. package/dist/views/PostManager/PostManagerView.js +179 -0
  220. package/dist/views/PostManager/PostStats.d.ts +11 -0
  221. package/dist/views/PostManager/PostStats.d.ts.map +1 -0
  222. package/dist/views/PostManager/PostStats.js +46 -0
  223. package/dist/views/PostManager/PostTable.d.ts +15 -0
  224. package/dist/views/PostManager/PostTable.d.ts.map +1 -0
  225. package/dist/views/PostManager/PostTable.js +77 -0
  226. package/dist/views/PostManager/index.d.ts +12 -0
  227. package/dist/views/PostManager/index.d.ts.map +1 -0
  228. package/dist/views/PostManager/index.js +11 -0
  229. package/dist/views/Preview/PreviewBridgeView.d.ts +12 -0
  230. package/dist/views/Preview/PreviewBridgeView.d.ts.map +1 -0
  231. package/dist/views/Preview/PreviewBridgeView.js +11 -0
  232. package/dist/views/Preview/index.d.ts +6 -0
  233. package/dist/views/Preview/index.d.ts.map +1 -0
  234. package/dist/views/Preview/index.js +4 -0
  235. package/dist/views/Settings/SettingsView.d.ts +10 -0
  236. package/dist/views/Settings/SettingsView.d.ts.map +1 -0
  237. package/dist/views/Settings/SettingsView.js +113 -0
  238. package/dist/views/Settings/index.d.ts +6 -0
  239. package/dist/views/Settings/index.d.ts.map +1 -0
  240. package/dist/views/Settings/index.js +4 -0
  241. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
  242. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
  243. package/dist/views/SlugSEO/SlugSEOManagerView.js +11 -0
  244. package/dist/views/SlugSEO/index.d.ts +6 -0
  245. package/dist/views/SlugSEO/index.d.ts.map +1 -0
  246. package/dist/views/SlugSEO/index.js +4 -0
  247. package/package.json +59 -55
  248. package/src/hooks/index.d.ts +8 -0
  249. package/src/hooks/index.d.ts.map +1 -0
  250. package/src/hooks/index.js +7 -0
  251. package/src/hooks/useBlog.d.ts +31 -0
  252. package/src/hooks/useBlog.d.ts.map +1 -0
  253. package/src/hooks/useBlog.js +57 -0
  254. package/src/hooks/useBlogs.d.ts +39 -0
  255. package/src/hooks/useBlogs.d.ts.map +1 -0
  256. package/src/hooks/useBlogs.js +82 -0
  257. package/src/hooks/useCategories.d.ts +9 -0
  258. package/src/hooks/useCategories.d.ts.map +1 -0
  259. package/src/hooks/useCategories.js +70 -0
  260. package/src/index.d.ts +55 -0
  261. package/src/index.d.ts.map +1 -0
  262. package/src/index.js +228 -0
  263. package/src/init.d.ts +40 -0
  264. package/src/init.d.ts.map +1 -0
  265. package/src/init.js +41 -0
  266. package/src/lib/blocks/BlockRenderer.d.ts +54 -0
  267. package/src/lib/blocks/BlockRenderer.d.ts.map +1 -0
  268. package/src/lib/blocks/BlockRenderer.js +54 -0
  269. package/src/lib/config-storage.d.ts +30 -0
  270. package/src/lib/config-storage.d.ts.map +1 -0
  271. package/src/lib/config-storage.js +31 -0
  272. package/src/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
  273. package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
  274. package/src/lib/layouts/blocks/ColumnsBlock.js +182 -0
  275. package/src/lib/layouts/blocks/SectionBlock.d.ts +25 -0
  276. package/src/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
  277. package/src/lib/layouts/blocks/SectionBlock.js +44 -0
  278. package/src/lib/layouts/index.d.ts +23 -0
  279. package/src/lib/layouts/index.d.ts.map +1 -0
  280. package/src/lib/layouts/index.js +45 -0
  281. package/src/lib/layouts/registerLayoutBlocks.d.ts +9 -0
  282. package/src/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
  283. package/src/lib/layouts/registerLayoutBlocks.js +60 -0
  284. package/src/lib/mappers/apiMapper.d.ts +66 -0
  285. package/src/lib/mappers/apiMapper.d.ts.map +1 -0
  286. package/src/lib/mappers/apiMapper.js +191 -0
  287. package/src/lib/rich-text/RichTextEditor.d.ts +45 -0
  288. package/src/lib/rich-text/RichTextEditor.d.ts.map +1 -0
  289. package/src/lib/rich-text/RichTextEditor.js +564 -0
  290. package/src/lib/rich-text/RichTextPreview.d.ts +16 -0
  291. package/src/lib/rich-text/RichTextPreview.d.ts.map +1 -0
  292. package/src/lib/rich-text/RichTextPreview.js +144 -0
  293. package/src/lib/rich-text/index.d.ts +9 -0
  294. package/src/lib/rich-text/index.d.ts.map +1 -0
  295. package/src/lib/rich-text/index.js +6 -0
  296. package/src/lib/utils/blockHelpers.d.ts +23 -0
  297. package/src/lib/utils/blockHelpers.d.ts.map +1 -0
  298. package/src/lib/utils/blockHelpers.js +65 -0
  299. package/src/lib/utils/configValidation.d.ts +23 -0
  300. package/src/lib/utils/configValidation.d.ts.map +1 -0
  301. package/src/lib/utils/configValidation.js +113 -0
  302. package/src/registry/BlockRegistry.d.ts +62 -0
  303. package/src/registry/BlockRegistry.d.ts.map +1 -0
  304. package/src/registry/BlockRegistry.js +112 -0
  305. package/src/registry/index.d.ts +6 -0
  306. package/src/registry/index.d.ts.map +1 -0
  307. package/src/registry/index.js +4 -0
  308. package/src/state/EditorContext.d.ts +45 -0
  309. package/src/state/EditorContext.d.ts.map +1 -0
  310. package/src/state/EditorContext.js +215 -0
  311. package/src/state/index.d.ts +7 -0
  312. package/src/state/index.d.ts.map +1 -0
  313. package/src/state/index.js +6 -0
  314. package/src/state/reducer.d.ts +11 -0
  315. package/src/state/reducer.d.ts.map +1 -0
  316. package/src/state/reducer.js +443 -0
  317. package/src/state/types.d.ts +162 -0
  318. package/src/state/types.d.ts.map +1 -0
  319. package/src/state/types.js +27 -0
  320. package/src/types/block.d.ts +221 -0
  321. package/src/types/block.d.ts.map +1 -0
  322. package/src/types/block.js +6 -0
  323. package/src/types/index.d.ts +8 -0
  324. package/src/types/index.d.ts.map +1 -0
  325. package/src/types/index.js +5 -0
  326. package/src/types/post.d.ts +136 -0
  327. package/src/types/post.d.ts.map +1 -0
  328. package/src/types/post.js +5 -0
  329. package/src/utils/client.d.ts +48 -0
  330. package/src/utils/client.d.ts.map +1 -0
  331. package/src/utils/client.js +77 -0
  332. package/src/utils/index.ts +0 -2
  333. package/src/views/CanvasEditor/BlockWrapper.d.ts +16 -0
  334. package/src/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
  335. package/src/views/CanvasEditor/BlockWrapper.js +276 -0
  336. package/src/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
  337. package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
  338. package/src/views/CanvasEditor/CanvasEditorView.js +209 -0
  339. package/src/views/CanvasEditor/EditorBody.d.ts +22 -0
  340. package/src/views/CanvasEditor/EditorBody.d.ts.map +1 -0
  341. package/src/views/CanvasEditor/EditorBody.js +505 -0
  342. package/src/views/CanvasEditor/EditorHeader.d.ts +18 -0
  343. package/src/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
  344. package/src/views/CanvasEditor/EditorHeader.js +101 -0
  345. package/src/views/CanvasEditor/LayoutContainer.d.ts +17 -0
  346. package/src/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
  347. package/src/views/CanvasEditor/LayoutContainer.js +222 -0
  348. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
  349. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
  350. package/src/views/CanvasEditor/SaveConfirmationModal.js +78 -0
  351. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
  352. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
  353. package/src/views/CanvasEditor/components/CustomBlockItem.js +44 -0
  354. package/src/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
  355. package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
  356. package/src/views/CanvasEditor/components/EditorCanvas.js +32 -0
  357. package/src/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
  358. package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
  359. package/src/views/CanvasEditor/components/EditorLibrary.js +25 -0
  360. package/src/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
  361. package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
  362. package/src/views/CanvasEditor/components/EditorSidebar.js +20 -0
  363. package/src/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
  364. package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
  365. package/src/views/CanvasEditor/components/ErrorBanner.js +8 -0
  366. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
  367. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
  368. package/src/views/CanvasEditor/components/FeaturedMediaSection.js +182 -0
  369. package/src/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
  370. package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
  371. package/src/views/CanvasEditor/components/LibraryItem.js +43 -0
  372. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
  373. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
  374. package/src/views/CanvasEditor/components/PrivacySettingsSection.js +63 -0
  375. package/src/views/CanvasEditor/components/index.d.ts +21 -0
  376. package/src/views/CanvasEditor/components/index.d.ts.map +1 -0
  377. package/src/views/CanvasEditor/components/index.js +12 -0
  378. package/src/views/CanvasEditor/hooks/index.d.ts +10 -0
  379. package/src/views/CanvasEditor/hooks/index.d.ts.map +1 -0
  380. package/src/views/CanvasEditor/hooks/index.js +9 -0
  381. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
  382. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
  383. package/src/views/CanvasEditor/hooks/useHeroBlock.js +79 -0
  384. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
  385. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  386. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.js +114 -0
  387. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
  388. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
  389. package/src/views/CanvasEditor/hooks/usePostLoader.js +32 -0
  390. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
  391. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
  392. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
  393. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
  394. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
  395. package/src/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
  396. package/src/views/CanvasEditor/index.d.ts +16 -0
  397. package/src/views/CanvasEditor/index.d.ts.map +1 -0
  398. package/src/views/CanvasEditor/index.js +9 -0
  399. package/src/views/PostManager/EmptyState.d.ts +10 -0
  400. package/src/views/PostManager/EmptyState.d.ts.map +1 -0
  401. package/src/views/PostManager/EmptyState.js +12 -0
  402. package/src/views/PostManager/PostActionsMenu.d.ts +12 -0
  403. package/src/views/PostManager/PostActionsMenu.d.ts.map +1 -0
  404. package/src/views/PostManager/PostActionsMenu.js +58 -0
  405. package/src/views/PostManager/PostCards.d.ts +15 -0
  406. package/src/views/PostManager/PostCards.d.ts.map +1 -0
  407. package/src/views/PostManager/PostCards.js +79 -0
  408. package/src/views/PostManager/PostFilters.d.ts +16 -0
  409. package/src/views/PostManager/PostFilters.d.ts.map +1 -0
  410. package/src/views/PostManager/PostFilters.js +10 -0
  411. package/src/views/PostManager/PostManagerView.d.ts +11 -0
  412. package/src/views/PostManager/PostManagerView.d.ts.map +1 -0
  413. package/src/views/PostManager/PostManagerView.js +174 -0
  414. package/src/views/PostManager/PostStats.d.ts +11 -0
  415. package/src/views/PostManager/PostStats.d.ts.map +1 -0
  416. package/src/views/PostManager/PostStats.js +46 -0
  417. package/src/views/PostManager/PostTable.d.ts +15 -0
  418. package/src/views/PostManager/PostTable.d.ts.map +1 -0
  419. package/src/views/PostManager/PostTable.js +79 -0
  420. package/src/views/PostManager/index.d.ts +12 -0
  421. package/src/views/PostManager/index.d.ts.map +1 -0
  422. package/src/views/PostManager/index.js +11 -0
  423. package/src/views/Preview/PreviewBridgeView.d.ts +12 -0
  424. package/src/views/Preview/PreviewBridgeView.d.ts.map +1 -0
  425. package/src/views/Preview/PreviewBridgeView.js +11 -0
  426. package/src/views/Preview/index.d.ts +6 -0
  427. package/src/views/Preview/index.d.ts.map +1 -0
  428. package/src/views/Preview/index.js +4 -0
  429. package/src/views/Settings/SettingsView.d.ts +10 -0
  430. package/src/views/Settings/SettingsView.d.ts.map +1 -0
  431. package/src/views/Settings/SettingsView.js +111 -0
  432. package/src/views/Settings/index.d.ts +6 -0
  433. package/src/views/Settings/index.d.ts.map +1 -0
  434. package/src/views/Settings/index.js +4 -0
  435. package/src/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
  436. package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
  437. package/src/views/SlugSEO/SlugSEOManagerView.js +11 -0
  438. package/src/views/SlugSEO/index.d.ts +6 -0
  439. package/src/views/SlugSEO/index.d.ts.map +1 -0
  440. package/src/views/SlugSEO/index.js +4 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Client Utilities
3
+ * Helper functions for fetching blog data in client applications
4
+ */
5
+ import { apiToBlogPost } from '../lib/mappers/apiMapper';
6
+ /**
7
+ * Fetch blog posts from the API
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * const { blogs, total } = await fetchBlogs({ limit: 5 });
12
+ * ```
13
+ */
14
+ export async function fetchBlogs(options = {}) {
15
+ const { limit = 10, skip = 0, status, admin = false, apiBaseUrl = '/api/plugin-blog', } = options;
16
+ const params = new URLSearchParams();
17
+ if (limit)
18
+ params.set('limit', limit.toString());
19
+ if (skip)
20
+ params.set('skip', skip.toString());
21
+ if (status)
22
+ params.set('status', status);
23
+ if (admin)
24
+ params.set('admin', 'true');
25
+ const url = `${apiBaseUrl}?${params.toString()}`;
26
+ const response = await fetch(url);
27
+ if (!response.ok) {
28
+ throw new Error(`Failed to fetch blogs: ${response.status}`);
29
+ }
30
+ const data = await response.json();
31
+ // Handle error response
32
+ if (data.error) {
33
+ throw new Error(data.error || 'Failed to fetch blogs');
34
+ }
35
+ // Convert API format to PostListItem format
36
+ const blogsArray = Array.isArray(data.blogs) ? data.blogs : [];
37
+ const convertedBlogs = blogsArray.map((apiDoc) => {
38
+ const blogPost = apiToBlogPost(apiDoc);
39
+ return {
40
+ id: blogPost.id,
41
+ title: blogPost.title,
42
+ slug: blogPost.slug,
43
+ excerpt: blogPost.metadata.excerpt || '',
44
+ status: blogPost.publication.status,
45
+ authorId: blogPost.publication.authorId || '',
46
+ updatedAt: blogPost.updatedAt,
47
+ featuredImage: blogPost.metadata.featuredImage,
48
+ };
49
+ });
50
+ return {
51
+ blogs: convertedBlogs,
52
+ total: data.total || convertedBlogs.length,
53
+ };
54
+ }
55
+ /**
56
+ * Fetch a single blog post by slug
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * const blog = await fetchBlog({ slug: 'my-blog-post' });
61
+ * ```
62
+ */
63
+ export async function fetchBlog(options) {
64
+ const { slug, apiBaseUrl = '/api/plugin-blog' } = options;
65
+ if (!slug) {
66
+ throw new Error('Slug is required');
67
+ }
68
+ const response = await fetch(`${apiBaseUrl}/${slug}`);
69
+ if (!response.ok) {
70
+ if (response.status === 404) {
71
+ throw new Error('Blog post not found');
72
+ }
73
+ throw new Error(`Failed to fetch blog: ${response.status}`);
74
+ }
75
+ const apiDoc = await response.json();
76
+ return apiToBlogPost(apiDoc);
77
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utilities
3
+ * Helper functions and utilities for the blog plugin
4
+ */
5
+ export * from './client';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,UAAU,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Utilities
3
+ * Helper functions and utilities for the blog plugin
4
+ */
5
+ export * from './client';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Block Wrapper Component
3
+ * Provides hover controls (Delete, Move, Settings) for each block
4
+ */
5
+ import { Block } from '../../types/block';
6
+ export interface BlockWrapperProps {
7
+ block: Block;
8
+ onUpdate: (data: Partial<Block['data']>) => void;
9
+ onDelete: () => void;
10
+ onMoveUp?: () => void;
11
+ onMoveDown?: () => void;
12
+ /** All blocks in the editor (for resolving child block IDs) */
13
+ allBlocks?: Block[];
14
+ }
15
+ export declare function BlockWrapper({ block, onUpdate, onDelete, onMoveUp, onMoveDown, allBlocks, }: BlockWrapperProps): import("react/jsx-runtime").JSX.Element;
16
+ //# sourceMappingURL=BlockWrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/BlockWrapper.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;CACvB;AAED,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAc,GACjB,EAAE,iBAAiB,2CAyenB"}
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Block Wrapper Component
3
+ * Provides hover controls (Delete, Move, Settings) for each block
4
+ */
5
+ 'use client';
6
+ import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
7
+ import { useState, useEffect, useRef } from 'react';
8
+ import { Plus, Trash2, ChevronUp, ChevronDown, Settings2, GripVertical, Copy } from 'lucide-react';
9
+ import { blockRegistry } from '../../registry/BlockRegistry';
10
+ import { getChildBlocks, isContainerBlock } from '../../lib/utils/blockHelpers';
11
+ import { useEditor } from '../../state/EditorContext';
12
+ export function BlockWrapper({ block, onUpdate, onDelete, onMoveUp, onMoveDown, allBlocks = [], }) {
13
+ const [isHovered, setIsHovered] = useState(false);
14
+ const [isControlsHovered, setIsControlsHovered] = useState(false);
15
+ const [showControls, setShowControls] = useState(false);
16
+ const [isSelectingText, setIsSelectingText] = useState(false);
17
+ const [showSettingsMenu, setShowSettingsMenu] = useState(false);
18
+ const hideTimeoutRef = useRef(null);
19
+ const settingsMenuRef = useRef(null);
20
+ const { helpers, state, dispatch } = useEditor();
21
+ const blockDefinition = blockRegistry.get(block.type);
22
+ // Check if this is a container block
23
+ const isContainer = isContainerBlock(block, blockRegistry);
24
+ // Get child blocks - if children are Block objects, use them directly
25
+ const childBlocks = isContainer && block.children && Array.isArray(block.children) && block.children.length > 0
26
+ ? (typeof block.children[0] === 'object'
27
+ ? block.children
28
+ : getChildBlocks(block, state.blocks))
29
+ : [];
30
+ // Handle delayed hide with timeout
31
+ useEffect(() => {
32
+ const shouldShow = isHovered || isControlsHovered;
33
+ if (shouldShow) {
34
+ // Clear any pending hide timeout
35
+ if (hideTimeoutRef.current) {
36
+ clearTimeout(hideTimeoutRef.current);
37
+ hideTimeoutRef.current = null;
38
+ }
39
+ // Show immediately
40
+ setShowControls(true);
41
+ }
42
+ else {
43
+ // Delay hiding by 500ms
44
+ hideTimeoutRef.current = setTimeout(() => {
45
+ setShowControls(false);
46
+ }, 500);
47
+ }
48
+ return () => {
49
+ if (hideTimeoutRef.current) {
50
+ clearTimeout(hideTimeoutRef.current);
51
+ }
52
+ };
53
+ }, [isHovered, isControlsHovered]);
54
+ if (!blockDefinition) {
55
+ return (_jsx("div", { className: "p-4 border border-red-300 dark:border-red-700 rounded-2xl bg-red-50 dark:bg-red-900/20", children: _jsxs("p", { className: "text-sm text-red-600 dark:text-red-400", children: ["Unknown block type: ", block.type] }) }));
56
+ }
57
+ const EditComponent = blockDefinition.components.Edit;
58
+ const handleDragStart = (e) => {
59
+ // Check if user is selecting text - if so, prevent dragging
60
+ const selection = window.getSelection();
61
+ if (selection && selection.toString().length > 0) {
62
+ e.preventDefault();
63
+ return;
64
+ }
65
+ // Prevent dragging if user was selecting text
66
+ if (isSelectingText) {
67
+ e.preventDefault();
68
+ return;
69
+ }
70
+ // Only allow dragging when the block is focused/selected (hovered)
71
+ if (!isHovered && !showControls) {
72
+ e.preventDefault();
73
+ return;
74
+ }
75
+ // Stop propagation to prevent parent containers from also handling the drag
76
+ e.stopPropagation();
77
+ console.log('[BlockWrapper] Drag Start:', {
78
+ blockId: block.id,
79
+ blockType: block.type,
80
+ blockData: block.data,
81
+ isContainer,
82
+ hasChildren: isContainer && childBlocks.length > 0,
83
+ });
84
+ e.dataTransfer.setData('block-id', block.id);
85
+ e.dataTransfer.setData('block-type', block.type);
86
+ e.dataTransfer.effectAllowed = 'move';
87
+ e.dataTransfer.setData('text/plain', ''); // Required for Firefox
88
+ // Store in a way that persists across components
89
+ if (typeof window !== 'undefined') {
90
+ window.__DRAGGED_BLOCK_ID__ = block.id;
91
+ console.log('[BlockWrapper] Stored global dragged block ID:', block.id);
92
+ }
93
+ };
94
+ // Track text selection
95
+ const handleMouseDown = (e) => {
96
+ // Check if clicking on an input, textarea, or contentEditable element
97
+ const target = e.target;
98
+ const isEditableElement = target.tagName === 'INPUT' ||
99
+ target.tagName === 'TEXTAREA' ||
100
+ target.isContentEditable ||
101
+ target.closest('input, textarea, [contenteditable="true"]');
102
+ if (isEditableElement) {
103
+ setIsSelectingText(true);
104
+ // Reset after mouse up
105
+ const handleMouseUp = () => {
106
+ setTimeout(() => {
107
+ const selection = window.getSelection();
108
+ if (!selection || selection.toString().length === 0) {
109
+ setIsSelectingText(false);
110
+ }
111
+ }, 100);
112
+ document.removeEventListener('mouseup', handleMouseUp);
113
+ };
114
+ document.addEventListener('mouseup', handleMouseUp);
115
+ }
116
+ };
117
+ // For hero blocks, only show controls when hovering over the image container
118
+ const isHeroBlock = block.type === 'hero';
119
+ const wrapperRef = useRef(null);
120
+ const handleMouseMove = (e) => {
121
+ if (isHeroBlock) {
122
+ // For hero blocks, check if mouse is actually over the image container element
123
+ const target = e.target;
124
+ // Check if we're over the image container (using data attribute for more reliable detection)
125
+ const imageContainer = target.closest('[data-hero-image-container]');
126
+ // Check if we're over an Image component (from plugin-images)
127
+ const imageElement = target.closest('[data-image-id]');
128
+ // Check if we're directly over an img tag
129
+ const isImgTag = target.tagName === 'IMG';
130
+ const isOverImage = !!(imageContainer || imageElement || isImgTag);
131
+ setIsHovered(isOverImage);
132
+ }
133
+ else if (!isHeroBlock) {
134
+ setIsHovered(true);
135
+ }
136
+ };
137
+ const handleMouseEnter = (e) => {
138
+ if (!isHeroBlock) {
139
+ setIsHovered(true);
140
+ }
141
+ else {
142
+ // For hero blocks, check position on enter
143
+ handleMouseMove(e);
144
+ }
145
+ };
146
+ const handleMouseLeave = () => {
147
+ setIsHovered(false);
148
+ };
149
+ // Close settings menu when clicking outside
150
+ useEffect(() => {
151
+ function handleClickOutside(event) {
152
+ if (settingsMenuRef.current && !settingsMenuRef.current.contains(event.target)) {
153
+ setShowSettingsMenu(false);
154
+ }
155
+ }
156
+ if (showSettingsMenu) {
157
+ document.addEventListener('mousedown', handleClickOutside);
158
+ }
159
+ return () => {
160
+ document.removeEventListener('mousedown', handleClickOutside);
161
+ };
162
+ }, [showSettingsMenu]);
163
+ // Generate a unique block ID
164
+ const generateBlockId = () => {
165
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
166
+ return crypto.randomUUID();
167
+ }
168
+ return `block-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
169
+ };
170
+ // Clone a block with new IDs (recursive for nested blocks)
171
+ const cloneBlock = (blockToClone) => {
172
+ const cloned = {
173
+ ...blockToClone,
174
+ id: generateBlockId(),
175
+ data: { ...blockToClone.data },
176
+ meta: blockToClone.meta ? { ...blockToClone.meta } : undefined,
177
+ };
178
+ // Handle children if they exist
179
+ if (blockToClone.children) {
180
+ if (Array.isArray(blockToClone.children) && blockToClone.children.length > 0) {
181
+ // Check if children are Block objects or IDs
182
+ if (typeof blockToClone.children[0] === 'object') {
183
+ cloned.children = blockToClone.children.map(cloneBlock);
184
+ }
185
+ else {
186
+ // If children are IDs, we need to find and clone the actual blocks
187
+ const childBlocks = getChildBlocks(blockToClone, allBlocks.length > 0 ? allBlocks : state.blocks);
188
+ cloned.children = childBlocks.map(cloneBlock);
189
+ }
190
+ }
191
+ }
192
+ return cloned;
193
+ };
194
+ const handleCopy = () => {
195
+ const clonedBlock = cloneBlock(block);
196
+ // Store in localStorage for persistence across components
197
+ if (typeof window !== 'undefined') {
198
+ localStorage.setItem('__BLOG_EDITOR_COPIED_BLOCK__', JSON.stringify(clonedBlock));
199
+ }
200
+ setShowSettingsMenu(false);
201
+ };
202
+ // Store block ID when hovering for paste context
203
+ useEffect(() => {
204
+ if (isHovered || showControls) {
205
+ if (typeof window !== 'undefined') {
206
+ window.__BLOG_EDITOR_HOVERED_BLOCK_ID__ = block.id;
207
+ }
208
+ }
209
+ }, [isHovered, showControls, block.id]);
210
+ return (_jsxs("div", { ref: wrapperRef, className: "group relative", onMouseEnter: handleMouseEnter, onMouseMove: isHeroBlock ? handleMouseMove : undefined, onMouseLeave: handleMouseLeave, onMouseDown: handleMouseDown, draggable: isHovered || showControls, onDragStart: handleDragStart, "data-block-wrapper": true, "data-block-id": block.id, children: [_jsxs("div", { className: `absolute -left-16 top-1/2 -translate-y-1/2 flex flex-col gap-2 transition-all duration-200 ${showControls ? 'opacity-100' : 'opacity-0 pointer-events-none'}`, onMouseEnter: () => setIsControlsHovered(true), onMouseLeave: () => setIsControlsHovered(false), children: [_jsx("button", { className: "p-2 text-neutral-500 dark:text-neutral-400 hover:text-primary dark:hover:text-primary bg-white dark:bg-neutral-800 rounded-lg shadow-sm border border-neutral-200 dark:border-neutral-700 hover:border-primary dark:hover:border-primary/50 transition-colors", title: "Add block above", children: _jsx(Plus, { size: 14 }) }), onMoveUp && (_jsx("button", { onClick: onMoveUp, className: "p-2 text-neutral-500 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white bg-white dark:bg-neutral-800 rounded-lg shadow-sm border border-neutral-200 dark:border-neutral-700 hover:border-neutral-300 dark:hover:border-neutral-600 transition-colors", title: "Move up", children: _jsx(ChevronUp, { size: 14 }) })), onMoveDown && (_jsx("button", { onClick: onMoveDown, className: "p-2 text-neutral-500 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white bg-white dark:bg-neutral-800 rounded-lg shadow-sm border border-neutral-200 dark:border-neutral-700 hover:border-neutral-300 dark:hover:border-neutral-600 transition-colors", title: "Move down", children: _jsx(ChevronDown, { size: 14 }) })), _jsx("button", { onClick: onDelete, className: "p-2 text-neutral-500 dark:text-neutral-400 hover:text-red-500 dark:hover:text-red-400 bg-white dark:bg-neutral-800 rounded-lg shadow-sm border border-neutral-200 dark:border-neutral-700 hover:border-red-500 dark:hover:border-red-500/50 transition-colors", title: "Delete block", children: _jsx(Trash2, { size: 14 }) })] }), _jsx("div", { className: `mb-2 transition-all relative ${isHovered || showControls || showSettingsMenu
211
+ ? 'opacity-100 translate-y-0'
212
+ : 'opacity-0 -translate-y-2 pointer-events-none'}`, onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), children: _jsxs("div", { className: "flex items-center justify-between px-2 py-1.5 rounded-lg backdrop-blur-sm border bg-neutral-50/95 dark:bg-neutral-800/95 border-neutral-200 dark:border-neutral-800", children: [_jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [_jsx(GripVertical, { size: 12, className: "cursor-grab active:cursor-grabbing shrink-0 text-neutral-400 dark:text-neutral-500" }), _jsx("span", { className: "text-[10px] font-black uppercase tracking-wider shrink-0 text-neutral-500 dark:text-neutral-400", children: blockDefinition.name }), block.type === 'columns' && (() => {
213
+ const columnCount = block.data.columnCount;
214
+ const layout = block.data.layout;
215
+ // Determine number of columns
216
+ let numColumns;
217
+ if (columnCount !== undefined && columnCount > 0) {
218
+ numColumns = columnCount;
219
+ }
220
+ else if (layout) {
221
+ // Legacy layout system
222
+ const layoutMap = {
223
+ '50-50': 2,
224
+ '33-66': 2,
225
+ '66-33': 2,
226
+ '25-25-25-25': 4,
227
+ '25-75': 2,
228
+ '75-25': 2,
229
+ };
230
+ numColumns = layoutMap[layout] || 2;
231
+ }
232
+ else {
233
+ numColumns = 2;
234
+ }
235
+ // Get column widths
236
+ const storedWidths = block.data.columnWidths;
237
+ const columnWidths = storedWidths && storedWidths.length === numColumns
238
+ ? storedWidths
239
+ : Array(numColumns).fill(Math.floor(100 / numColumns));
240
+ return (_jsx("div", { className: "flex items-center gap-1.5 ml-4 flex-1 min-w-0", children: Array.from({ length: numColumns }).map((_, colIndex) => (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("input", { type: "number", min: "10", max: "90", step: "1", value: columnWidths[colIndex] || 50, onChange: (e) => {
241
+ const newWidth = parseInt(e.target.value) || 50;
242
+ const newWidths = [...columnWidths];
243
+ newWidths[colIndex] = Math.max(10, Math.min(90, newWidth));
244
+ // Normalize remaining columns to sum to 100
245
+ const remainingTotal = newWidths.reduce((sum, w, i) => i === colIndex ? sum : sum + w, 0);
246
+ const remainingTarget = 100 - newWidths[colIndex];
247
+ if (remainingTotal > 0 && remainingTarget > 0) {
248
+ const scale = remainingTarget / remainingTotal;
249
+ newWidths.forEach((w, i) => {
250
+ if (i !== colIndex) {
251
+ newWidths[i] = Math.round(w * scale);
252
+ }
253
+ });
254
+ }
255
+ // Ensure sum is exactly 100
256
+ const finalTotal = newWidths.reduce((sum, w) => sum + w, 0);
257
+ if (finalTotal !== 100) {
258
+ const diff = 100 - finalTotal;
259
+ const lastIndex = newWidths.length - 1;
260
+ newWidths[lastIndex] = Math.max(10, newWidths[lastIndex] + diff);
261
+ }
262
+ onUpdate({
263
+ ...block.data,
264
+ columnWidths: newWidths,
265
+ layout: undefined, // Clear layout when using custom widths
266
+ });
267
+ }, onClick: (e) => e.stopPropagation(), className: "w-12 text-[10px] font-bold bg-white dark:bg-neutral-900/50 border border-neutral-300 dark:border-neutral-700 px-1.5 py-0.5 rounded outline-none focus:border-primary transition-all dark:text-neutral-100 text-center" }), _jsx("span", { className: "text-[9px] text-neutral-400 dark:text-neutral-500", children: "%" })] }, colIndex))) }));
268
+ })()] }), _jsxs("div", { className: "relative shrink-0 z-20", ref: settingsMenuRef, children: [_jsx("button", { onClick: (e) => {
269
+ e.stopPropagation();
270
+ setShowSettingsMenu(!showSettingsMenu);
271
+ }, className: "p-1 rounded transition-colors text-neutral-400 dark:text-neutral-500 hover:text-neutral-950 dark:hover:text-white hover:bg-neutral-100 dark:hover:bg-neutral-800 relative z-20", title: "Block settings", children: _jsx(Settings2, { size: 12 }) }), showSettingsMenu && (_jsx("div", { className: "absolute right-0 top-full mt-1 w-40 bg-white dark:bg-neutral-900 border border-neutral-300 dark:border-neutral-700 rounded-lg shadow-xl z-20 overflow-hidden", children: _jsxs("button", { onClick: (e) => {
272
+ e.stopPropagation();
273
+ handleCopy();
274
+ }, className: "w-full flex items-center gap-2 px-3 py-2 text-xs font-bold text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800 transition-colors", children: [_jsx(Copy, { size: 14 }), _jsx("span", { children: "Copy" })] }) }))] })] }) }), _jsx("div", { className: `relative rounded-xl border-2 transition-all ${showControls
275
+ ? 'border-primary/60 dark:border-primary/40 bg-primary/5 dark:bg-primary/10'
276
+ : 'border-neutral-200 dark:border-neutral-700 bg-transparent'}`, children: _jsx("div", { className: "relative", style: { userSelect: 'text' }, children: isContainer && (block.type === 'section' || block.type === 'columns') ? (_jsx(EditComponent, { block: block, onUpdate: onUpdate, onDelete: onDelete, isSelected: isHovered, childBlocks: childBlocks, onChildBlockAdd: (type, index, containerId) => {
277
+ helpers.addBlock(type, index, containerId || block.id);
278
+ }, onChildBlockUpdate: (id, data, containerId) => {
279
+ helpers.updateBlock(id, data);
280
+ }, onChildBlockDelete: (id, containerId) => {
281
+ helpers.deleteBlock(id);
282
+ }, onChildBlockMove: (id, newIndex, containerId) => {
283
+ helpers.moveBlock(id, newIndex, containerId || block.id);
284
+ } })) : (_jsx(EditComponent, { block: block, onUpdate: onUpdate, onDelete: onDelete, isSelected: isHovered })) }) })] }));
285
+ }
@@ -0,0 +1,14 @@
1
+ export interface CanvasEditorViewProps {
2
+ postId?: string;
3
+ siteId: string;
4
+ locale: string;
5
+ /** Enable dark mode for content area and wrappers (default: true) */
6
+ darkMode?: boolean;
7
+ /** Background colors for the editor */
8
+ backgroundColors?: {
9
+ light: string;
10
+ dark?: string;
11
+ };
12
+ }
13
+ export declare function CanvasEditorView({ postId, darkMode, backgroundColors: propsBackgroundColors, siteId, locale }: CanvasEditorViewProps): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=CanvasEditorView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasEditorView.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/CanvasEditorView.tsx"],"names":[],"mappings":"AAaA,MAAM,WAAW,qBAAqB;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CAsTpI"}
@@ -0,0 +1,215 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useEffect, useRef } from 'react';
4
+ import { useEditor } from '../../state/EditorContext';
5
+ import { EditorHeader } from './EditorHeader';
6
+ import { ErrorBanner } from './components/ErrorBanner';
7
+ import { EditorLibrary } from './components/EditorLibrary';
8
+ import { EditorCanvas } from './components/EditorCanvas';
9
+ import { EditorSidebar } from './components/EditorSidebar';
10
+ import { usePostLoader, useHeroBlock, useRegisteredBlocks, useKeyboardShortcuts, useUnsavedChanges } from './hooks';
11
+ export function CanvasEditorView({ postId, darkMode, backgroundColors: propsBackgroundColors, siteId, locale }) {
12
+ const { state, helpers, dispatch, darkMode: contextDarkMode, backgroundColors: contextBackgroundColors, canUndo, canRedo } = useEditor();
13
+ const effectiveDarkMode = darkMode !== undefined ? darkMode : contextDarkMode;
14
+ const effectiveBackgroundColors = propsBackgroundColors || contextBackgroundColors;
15
+ const [isSidebarOpen, setSidebarOpen] = useState(true);
16
+ const [isLibraryOpen, setLibraryOpen] = useState(true);
17
+ const [isPreviewMode, setIsPreviewMode] = useState(false);
18
+ const [isSaving, setIsSaving] = useState(false);
19
+ const [saveError, setSaveError] = useState(null);
20
+ // Get registered blocks
21
+ const registeredBlocks = useRegisteredBlocks();
22
+ // Hero block management
23
+ const { heroBlock, setHeroBlock, heroBlockDefinition } = useHeroBlock(state, registeredBlocks);
24
+ // Post loading
25
+ const { isLoadingPost } = usePostLoader(postId, state.postId, (post) => {
26
+ helpers.loadPost(post);
27
+ // After loading, ensure we're marked as clean
28
+ // Use setTimeout to ensure this runs after the reducer has processed LOAD_POST
29
+ setTimeout(() => {
30
+ dispatch({ type: 'MARK_CLEAN' });
31
+ }, 0);
32
+ }, () => setHeroBlock(null));
33
+ // Track if we just loaded a post to prevent marking as dirty during cleanup
34
+ const justLoadedRef = useRef(false);
35
+ const previousIsLoadingRef = useRef(false);
36
+ const loadingCleanupTimerRef = useRef(null);
37
+ // Mark when post loading completes and ensure it stays clean after all effects
38
+ useEffect(() => {
39
+ // Detect when loading just finished (was loading, now not loading, and we have a postId)
40
+ const loadingJustFinished = previousIsLoadingRef.current && !isLoadingPost && state.postId;
41
+ if (loadingJustFinished) {
42
+ justLoadedRef.current = true;
43
+ // Clear any existing cleanup timer
44
+ if (loadingCleanupTimerRef.current) {
45
+ clearTimeout(loadingCleanupTimerRef.current);
46
+ }
47
+ // Wait for all effects to complete, then ensure we're marked as clean
48
+ // Use multiple animation frames + setTimeout to ensure all effects have run
49
+ requestAnimationFrame(() => {
50
+ requestAnimationFrame(() => {
51
+ loadingCleanupTimerRef.current = setTimeout(() => {
52
+ // Force mark as clean after loading - this ensures cleanup effects don't leave us dirty
53
+ console.log('[CanvasEditorView] Post loading complete - ensuring clean state');
54
+ dispatch({ type: 'MARK_CLEAN' });
55
+ justLoadedRef.current = false;
56
+ loadingCleanupTimerRef.current = null;
57
+ }, 500); // Delay to ensure all effects complete
58
+ });
59
+ });
60
+ }
61
+ // Update ref
62
+ previousIsLoadingRef.current = isLoadingPost;
63
+ return () => {
64
+ if (loadingCleanupTimerRef.current) {
65
+ clearTimeout(loadingCleanupTimerRef.current);
66
+ loadingCleanupTimerRef.current = null;
67
+ }
68
+ };
69
+ }, [isLoadingPost, state.postId, dispatch]);
70
+ // Keyboard shortcuts
71
+ useKeyboardShortcuts(state, dispatch, canUndo, canRedo, helpers.undo, helpers.redo);
72
+ // Unsaved changes warning and auto-save
73
+ const { autoSaveEnabled, setAutoSaveEnabled, countdown, saveStatus } = useUnsavedChanges({
74
+ state,
75
+ isDirty: state.isDirty,
76
+ onSave: async () => {
77
+ // Preserve current status: if already published, keep it published
78
+ // Otherwise save as draft
79
+ const shouldPublish = state.status === 'published';
80
+ await handleSave(shouldPublish);
81
+ },
82
+ heroBlock,
83
+ postId: state.postId,
84
+ });
85
+ // Listen for hero title updates from HeroBlock (if it dispatches events)
86
+ useEffect(() => {
87
+ const handleHeroTitleUpdate = (e) => {
88
+ dispatch({ type: 'SET_TITLE', payload: e.detail });
89
+ };
90
+ window.addEventListener('hero-title-update', handleHeroTitleUpdate);
91
+ return () => window.removeEventListener('hero-title-update', handleHeroTitleUpdate);
92
+ }, [dispatch]);
93
+ // Remove any hero blocks from the content blocks array
94
+ // Note: This effect will mark as dirty, but the loading cleanup effect will fix it
95
+ useEffect(() => {
96
+ const heroBlocksInContent = state.blocks.filter(b => b.type === 'hero');
97
+ if (heroBlocksInContent.length > 0) {
98
+ heroBlocksInContent.forEach(block => {
99
+ dispatch({ type: 'DELETE_BLOCK', payload: { id: block.id } });
100
+ });
101
+ // Don't mark as clean here - let the loading cleanup effect handle it
102
+ // This ensures we wait for all effects to complete before marking clean
103
+ }
104
+ }, [state.blocks, dispatch]);
105
+ // Filter out hero blocks from content blocks
106
+ const contentBlocks = state.blocks.filter(b => b.type !== 'hero');
107
+ // Handler to add block at the bottom when clicking (not dragging)
108
+ const handleAddBlockAtBottom = (blockType) => {
109
+ // Add at the end of content blocks (excluding hero)
110
+ helpers.addBlock(blockType, contentBlocks.length, undefined);
111
+ };
112
+ // Handle save
113
+ const handleSave = async (publish) => {
114
+ setIsSaving(true);
115
+ setSaveError(null);
116
+ try {
117
+ // Status should already be set in EditorHeader, but verify and log
118
+ console.log('[CanvasEditorView] onSave called with publish:', publish, 'current status:', state.status);
119
+ // Only change status if explicitly requested (publish is true or false)
120
+ // If publish is undefined, preserve the current status (used for autosave)
121
+ if (publish === true && state.status !== 'published') {
122
+ console.warn('[CanvasEditorView] Status mismatch! Setting to published...');
123
+ dispatch({ type: 'SET_STATUS', payload: 'published' });
124
+ await new Promise(resolve => setTimeout(resolve, 100));
125
+ }
126
+ else if (publish === false && state.status !== 'draft' && state.status !== 'published') {
127
+ // Only set to draft if not already published (preserve published status)
128
+ // This prevents autosave from changing published posts back to draft
129
+ console.warn('[CanvasEditorView] Status mismatch! Setting to draft...');
130
+ dispatch({ type: 'SET_STATUS', payload: 'draft' });
131
+ await new Promise(resolve => setTimeout(resolve, 100));
132
+ }
133
+ console.log('[CanvasEditorView] Final status before save:', state.status);
134
+ // Pass hero block to save function so it can be included in the saved data
135
+ await helpers.save(heroBlock);
136
+ setIsSaving(false);
137
+ }
138
+ catch (error) {
139
+ console.error('[CanvasEditorView] Save error:', error);
140
+ // Extract and format user-friendly error message
141
+ let errorMessage = error.message || 'Failed to save post';
142
+ // Make error messages more user-friendly
143
+ if (errorMessage.includes('Missing required fields')) {
144
+ errorMessage = errorMessage.replace('Missing required fields for publishing:', 'To publish, please fill in:');
145
+ }
146
+ else if (errorMessage.includes('All required fields')) {
147
+ errorMessage = 'To publish, please fill in all required fields: summary, featured image, category, and content.';
148
+ }
149
+ else if (errorMessage.includes('Unauthorized')) {
150
+ errorMessage = 'You are not authorized to save this post. Please log in again.';
151
+ }
152
+ else if (errorMessage.includes('Failed to save')) {
153
+ errorMessage = 'Unable to save the post. Please check your connection and try again.';
154
+ }
155
+ setSaveError(errorMessage);
156
+ setIsSaving(false); // Always reset saving state on error
157
+ throw error; // Re-throw so EditorHeader can handle it
158
+ }
159
+ };
160
+ // Handle hero block update
161
+ const handleHeroBlockUpdate = (data) => {
162
+ if (!heroBlock)
163
+ return;
164
+ setHeroBlock({
165
+ ...heroBlock,
166
+ data: { ...heroBlock.data, ...data },
167
+ });
168
+ // Sync title to editor state
169
+ if (data.title !== undefined && typeof data.title === 'string') {
170
+ dispatch({ type: 'SET_TITLE', payload: data.title });
171
+ }
172
+ // Sync summary to editor state metadata
173
+ if (data.summary !== undefined && typeof data.summary === 'string') {
174
+ dispatch({
175
+ type: 'SET_METADATA',
176
+ payload: { excerpt: data.summary }
177
+ });
178
+ }
179
+ // Hero image and featured image are completely independent
180
+ // Do NOT sync hero image to featured image
181
+ // The featured image is a separate thumbnail that the client adjusts independently
182
+ // Sync category to editor state metadata
183
+ if (data.category !== undefined && typeof data.category === 'string') {
184
+ dispatch({
185
+ type: 'SET_METADATA',
186
+ payload: {
187
+ categories: data.category.trim() ? [data.category.trim()] : []
188
+ }
189
+ });
190
+ }
191
+ };
192
+ // Handle hero block delete/reset
193
+ const handleHeroBlockDelete = () => {
194
+ if (!heroBlock || !heroBlockDefinition)
195
+ return;
196
+ const defaultData = heroBlockDefinition.defaultData || {};
197
+ setHeroBlock({
198
+ ...heroBlock,
199
+ data: { ...defaultData },
200
+ });
201
+ };
202
+ return (_jsx("div", { className: "h-full rounded-[2.5rem] w-full bg-dashboard-card text-dashboard-text flex flex-col font-sans transition-colors duration-300 overflow-hidden relative", children: _jsxs("main", { className: "flex flex-1 flex-col relative min-h-0", children: [_jsx(ErrorBanner, { error: saveError, onDismiss: () => setSaveError(null) }), _jsx(EditorHeader, { isLibraryOpen: isLibraryOpen, onLibraryToggle: () => setLibraryOpen(!isLibraryOpen), isPreviewMode: isPreviewMode, onPreviewToggle: () => setIsPreviewMode(!isPreviewMode), isSidebarOpen: isSidebarOpen, onSidebarToggle: () => setSidebarOpen(!isSidebarOpen), isSaving: isSaving, onSave: handleSave, onSaveError: (error) => {
203
+ // Format error message for display
204
+ if (error) {
205
+ let formattedError = error;
206
+ if (formattedError.includes('Missing required fields')) {
207
+ formattedError = formattedError.replace('Missing required fields for publishing:', 'To publish, please fill in:');
208
+ }
209
+ setSaveError(formattedError);
210
+ }
211
+ else {
212
+ setSaveError(null);
213
+ }
214
+ }, autoSaveEnabled: autoSaveEnabled, onAutoSaveToggle: setAutoSaveEnabled, isDirty: state.isDirty, autoSaveCountdown: countdown, autoSaveStatus: saveStatus }), _jsxs("div", { className: "flex flex-1 relative overflow-hidden min-h-0 flex-nowrap", children: [!isPreviewMode && (_jsx("aside", { className: `transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] border-r border-dashboard-border bg-dashboard-sidebar overflow-y-auto overflow-x-hidden h-full ${isLibraryOpen ? 'w-72' : 'w-0 opacity-0 pointer-events-none'}`, children: _jsx(EditorLibrary, { registeredBlocks: registeredBlocks, onAddBlock: handleAddBlockAtBottom }) })), _jsx(EditorCanvas, { isPreviewMode: isPreviewMode, heroBlock: heroBlock, heroBlockDefinition: heroBlockDefinition, contentBlocks: contentBlocks, title: state.title, siteId: siteId, locale: locale, darkMode: effectiveDarkMode, backgroundColors: effectiveBackgroundColors, featuredImage: state.metadata.featuredImage, onTitleChange: (title) => dispatch({ type: 'SET_TITLE', payload: title }), onHeroBlockUpdate: handleHeroBlockUpdate, onHeroBlockDelete: handleHeroBlockDelete, onBlockAdd: (type, index, containerId) => helpers.addBlock(type, index, containerId), onBlockUpdate: (id, data) => helpers.updateBlock(id, data), onBlockDelete: (id) => helpers.deleteBlock(id), onBlockMove: (id, newIndex, containerId) => helpers.moveBlock(id, newIndex, containerId) }), !isPreviewMode && (_jsx("aside", { className: `transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] border-l border-dashboard-border bg-dashboard-sidebar overflow-y-auto overflow-x-hidden h-full ${isSidebarOpen ? 'w-80' : 'w-0 opacity-0 pointer-events-none'}`, children: _jsx(EditorSidebar, { slug: state.slug, seo: state.seo, metadata: state.metadata, heroBlock: heroBlock, status: state.status, onSEOUpdate: (seo) => dispatch({ type: 'SET_SEO', payload: seo }), onMetadataUpdate: (metadata) => dispatch({ type: 'SET_METADATA', payload: metadata }) }) }))] })] }) }));
215
+ }