@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,90 @@
1
+ import { useState, useEffect, useMemo } from 'react';
2
+ import { blockRegistry } from '../../../registry/BlockRegistry';
3
+ // Generate a unique block ID
4
+ function generateBlockId() {
5
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
6
+ return crypto.randomUUID();
7
+ }
8
+ return `block-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
9
+ }
10
+ export function useHeroBlock(state, registeredBlocks) {
11
+ const [heroBlock, setHeroBlock] = useState(null);
12
+ // Get Hero block definition from registered blocks (REQUIRED)
13
+ const heroBlockDefinition = useMemo(() => {
14
+ return blockRegistry.get('hero');
15
+ }, [registeredBlocks]);
16
+ // Initialize hero block if Hero block definition exists
17
+ useEffect(() => {
18
+ if (heroBlockDefinition) {
19
+ // Get default data from block definition
20
+ const heroData = heroBlockDefinition.defaultData || {};
21
+ // Initialize hero block only if it doesn't exist yet
22
+ setHeroBlock(prev => {
23
+ if (!prev) {
24
+ // First, try to find hero block in contentBlocks (from loaded post)
25
+ const heroBlockFromContent = state.blocks.find(block => block.type === 'hero');
26
+ if (heroBlockFromContent) {
27
+ return heroBlockFromContent;
28
+ }
29
+ // If no hero block in contentBlocks, initialize from defaults
30
+ // Hero image and featured image are completely independent - no syncing
31
+ const initialData = {
32
+ ...heroData,
33
+ title: state.title || heroData.title || '',
34
+ summary: state.metadata.excerpt || heroData.summary || '',
35
+ image: heroData.image, // Use default image, not featured image
36
+ };
37
+ return {
38
+ id: generateBlockId(),
39
+ type: 'hero',
40
+ data: initialData,
41
+ };
42
+ }
43
+ // Keep existing hero block data - let the Edit component manage it
44
+ return prev;
45
+ });
46
+ }
47
+ else {
48
+ setHeroBlock(null);
49
+ }
50
+ }, [heroBlockDefinition, state.blocks, state.title, state.metadata.excerpt]);
51
+ // Sync hero block with editor state when post is loaded (for existing posts)
52
+ // BUT: Never sync image from featured image to hero - they are independent
53
+ // Only sync title, summary, and category
54
+ useEffect(() => {
55
+ if (heroBlock && heroBlockDefinition && state.postId) {
56
+ // Only update if the hero block data doesn't match the editor state
57
+ // This prevents overwriting user edits with stale data
58
+ const currentTitle = heroBlock.data?.title || '';
59
+ const currentSummary = heroBlock.data?.summary || '';
60
+ const currentCategory = heroBlock.data?.category || '';
61
+ const stateTitle = state.title || '';
62
+ const stateSummary = state.metadata.excerpt || '';
63
+ const stateCategory = state.metadata.categories?.[0] || '';
64
+ // Check if hero block is out of sync with editor state
65
+ // NOTE: We do NOT sync image anymore - hero and featured image are independent
66
+ const titleMismatch = currentTitle !== stateTitle;
67
+ const summaryMismatch = currentSummary !== stateSummary;
68
+ const categoryMismatch = currentCategory !== stateCategory;
69
+ // Only update title, summary, and category - NEVER update image
70
+ // The hero block image should come from contentBlocks, not from featured image
71
+ if ((titleMismatch || summaryMismatch || categoryMismatch) && (stateTitle || stateSummary || stateCategory)) {
72
+ setHeroBlock({
73
+ ...heroBlock,
74
+ data: {
75
+ ...heroBlock.data,
76
+ title: stateTitle || heroBlock.data?.title || '',
77
+ summary: stateSummary || heroBlock.data?.summary || '',
78
+ // DO NOT sync image - keep hero block's own image
79
+ category: stateCategory || heroBlock.data?.category || '',
80
+ },
81
+ });
82
+ }
83
+ }
84
+ }, [state.postId, state.title, state.metadata.excerpt, state.metadata.categories, heroBlockDefinition, heroBlock]);
85
+ return {
86
+ heroBlock,
87
+ setHeroBlock,
88
+ heroBlockDefinition,
89
+ };
90
+ }
@@ -0,0 +1,3 @@
1
+ import type { EditorState } from '../../../state/types';
2
+ export declare function useKeyboardShortcuts(state: EditorState, dispatch: (action: any) => void, canUndo: boolean, canRedo: boolean, undo: () => void, redo: () => void): void;
3
+ //# sourceMappingURL=useKeyboardShortcuts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useKeyboardShortcuts.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/useKeyboardShortcuts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAUxD,wBAAgB,oBAAoB,CAChC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,EAC/B,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,MAAM,IAAI,EAChB,IAAI,EAAE,MAAM,IAAI,QA2HnB"}
@@ -0,0 +1,119 @@
1
+ import { useEffect } from 'react';
2
+ // Generate a unique block ID
3
+ function generateBlockId() {
4
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
5
+ return crypto.randomUUID();
6
+ }
7
+ return `block-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
8
+ }
9
+ export function useKeyboardShortcuts(state, dispatch, canUndo, canRedo, undo, redo) {
10
+ useEffect(() => {
11
+ const handleKeyDown = (e) => {
12
+ // Don't handle shortcuts if user is typing in an input/textarea/contentEditable
13
+ const target = e.target;
14
+ const isEditableElement = target.tagName === 'INPUT' ||
15
+ target.tagName === 'TEXTAREA' ||
16
+ target.isContentEditable ||
17
+ target.closest('input, textarea, [contenteditable="true"]');
18
+ // Check for Ctrl+Z / Cmd+Z (Undo)
19
+ if ((e.ctrlKey || e.metaKey) && e.key === 'z' && !e.shiftKey) {
20
+ if (!isEditableElement) {
21
+ e.preventDefault();
22
+ e.stopPropagation();
23
+ if (canUndo) {
24
+ undo();
25
+ }
26
+ return;
27
+ }
28
+ }
29
+ // Check for Ctrl+Shift+Z / Cmd+Shift+Z or Ctrl+Y / Cmd+Y (Redo)
30
+ if (((e.ctrlKey || e.metaKey) && e.shiftKey && e.key === 'z') || ((e.ctrlKey || e.metaKey) && e.key === 'y')) {
31
+ if (!isEditableElement) {
32
+ e.preventDefault();
33
+ e.stopPropagation();
34
+ if (canRedo) {
35
+ redo();
36
+ }
37
+ return;
38
+ }
39
+ }
40
+ // Check for Ctrl+V (Windows/Linux) or Cmd+V (Mac)
41
+ if ((e.ctrlKey || e.metaKey) && e.key === 'v') {
42
+ // Don't paste if user is typing in an input/textarea/contentEditable
43
+ const target = e.target;
44
+ const isEditableElement = target.tagName === 'INPUT' ||
45
+ target.tagName === 'TEXTAREA' ||
46
+ target.isContentEditable ||
47
+ target.closest('input, textarea, [contenteditable="true"]');
48
+ if (isEditableElement) {
49
+ return; // Let the browser handle paste in editable elements
50
+ }
51
+ // Check if there's a copied block
52
+ if (typeof window !== 'undefined') {
53
+ const copiedBlockJson = localStorage.getItem('__BLOG_EDITOR_COPIED_BLOCK__');
54
+ if (copiedBlockJson) {
55
+ try {
56
+ e.preventDefault();
57
+ e.stopPropagation();
58
+ const copiedBlock = JSON.parse(copiedBlockJson);
59
+ // Clone a block with new IDs (recursive for nested blocks)
60
+ const cloneBlock = (blockToClone) => {
61
+ const cloned = {
62
+ ...blockToClone,
63
+ id: generateBlockId(),
64
+ data: { ...blockToClone.data },
65
+ meta: blockToClone.meta ? { ...blockToClone.meta } : undefined,
66
+ };
67
+ // Handle children if they exist
68
+ if (blockToClone.children) {
69
+ if (Array.isArray(blockToClone.children) && blockToClone.children.length > 0) {
70
+ if (typeof blockToClone.children[0] === 'object') {
71
+ cloned.children = blockToClone.children.map(cloneBlock);
72
+ }
73
+ else {
74
+ // If children are IDs, find and clone the actual blocks
75
+ const allBlocks = state.blocks;
76
+ const childIds = blockToClone.children;
77
+ const childBlocks = childIds
78
+ .map((childId) => allBlocks.find(b => b.id === childId))
79
+ .filter((b) => b !== undefined);
80
+ cloned.children = childBlocks.map(cloneBlock);
81
+ }
82
+ }
83
+ }
84
+ return cloned;
85
+ };
86
+ const pastedBlock = cloneBlock(copiedBlock);
87
+ // Find where to paste - use hovered block or selected block, or paste at end
88
+ const hoveredBlockId = window.__BLOG_EDITOR_HOVERED_BLOCK_ID__;
89
+ const targetBlockId = hoveredBlockId || state.selectedBlockId;
90
+ let pasteIndex;
91
+ if (targetBlockId) {
92
+ const targetIndex = state.blocks.findIndex(b => b.id === targetBlockId);
93
+ if (targetIndex !== -1) {
94
+ pasteIndex = targetIndex + 1;
95
+ }
96
+ }
97
+ // Dispatch ADD_BLOCK with the full block structure
98
+ dispatch({
99
+ type: 'ADD_BLOCK',
100
+ payload: {
101
+ block: pastedBlock,
102
+ index: pasteIndex,
103
+ containerId: undefined
104
+ }
105
+ });
106
+ }
107
+ catch (error) {
108
+ console.error('Failed to paste block:', error);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ };
114
+ window.addEventListener('keydown', handleKeyDown);
115
+ return () => {
116
+ window.removeEventListener('keydown', handleKeyDown);
117
+ };
118
+ }, [state.blocks, state.selectedBlockId, dispatch, canUndo, canRedo, undo, redo]);
119
+ }
@@ -0,0 +1,5 @@
1
+ import type { BlogPost } from '../../../types/post';
2
+ export declare function usePostLoader(postId: string | undefined, currentPostId: string | null, loadPost: (post: BlogPost) => void, resetHeroBlock: () => void): {
3
+ isLoadingPost: boolean;
4
+ };
5
+ //# sourceMappingURL=usePostLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePostLoader.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/usePostLoader.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,wBAAgB,aAAa,CACzB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,IAAI,EAClC,cAAc,EAAE,MAAM,IAAI;;EA8B7B"}
@@ -0,0 +1,32 @@
1
+ import { useEffect, useState } from 'react';
2
+ import { apiToBlogPost } from '../../../lib/mappers/apiMapper';
3
+ export function usePostLoader(postId, currentPostId, loadPost, resetHeroBlock) {
4
+ const [isLoadingPost, setIsLoadingPost] = useState(false);
5
+ useEffect(() => {
6
+ if (postId && !currentPostId) {
7
+ const loadPostData = async () => {
8
+ try {
9
+ setIsLoadingPost(true);
10
+ // Reset hero block before loading new post so it gets re-initialized from the new post's blocks
11
+ resetHeroBlock();
12
+ const response = await fetch(`/api/plugin-blog/${postId}`);
13
+ if (!response.ok) {
14
+ throw new Error('Failed to load post');
15
+ }
16
+ const apiDoc = await response.json();
17
+ const blogPost = apiToBlogPost(apiDoc);
18
+ loadPost(blogPost);
19
+ }
20
+ catch (error) {
21
+ console.error('Failed to load post:', error);
22
+ alert('Failed to load post. Please try again.');
23
+ }
24
+ finally {
25
+ setIsLoadingPost(false);
26
+ }
27
+ };
28
+ loadPostData();
29
+ }
30
+ }, [postId, currentPostId, loadPost, resetHeroBlock]);
31
+ return { isLoadingPost };
32
+ }
@@ -0,0 +1,2 @@
1
+ export declare function useRegisteredBlocks(): import("../../..").BlockTypeDefinition[];
2
+ //# sourceMappingURL=useRegisteredBlocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRegisteredBlocks.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/useRegisteredBlocks.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,6CAmDlC"}
@@ -0,0 +1,47 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { blockRegistry } from '../../../registry/BlockRegistry';
3
+ export function useRegisteredBlocks() {
4
+ const [registeredBlocks, setRegisteredBlocks] = useState(() => {
5
+ const initial = blockRegistry.getAll();
6
+ return initial;
7
+ });
8
+ // Watch for registry changes and update state
9
+ useEffect(() => {
10
+ // Check immediately
11
+ const checkBlocks = () => {
12
+ const currentBlocks = blockRegistry.getAll();
13
+ const hasChanged = currentBlocks.length !== registeredBlocks.length ||
14
+ currentBlocks.some((b, i) => b.type !== registeredBlocks[i]?.type) ||
15
+ registeredBlocks.some((b, i) => b.type !== currentBlocks[i]?.type);
16
+ if (hasChanged) {
17
+ setRegisteredBlocks([...currentBlocks]);
18
+ }
19
+ };
20
+ // Initial check
21
+ checkBlocks();
22
+ // Poll for registry changes (blocks are registered asynchronously in useEffect)
23
+ // Use a shorter interval initially, then longer
24
+ let pollCount = 0;
25
+ const interval = setInterval(() => {
26
+ pollCount++;
27
+ checkBlocks();
28
+ // Stop polling after 5 seconds (25 checks at 200ms)
29
+ if (pollCount > 25) {
30
+ clearInterval(interval);
31
+ }
32
+ }, 200);
33
+ // Also check after delays to catch initial registrations
34
+ const timeouts = [
35
+ setTimeout(checkBlocks, 50),
36
+ setTimeout(checkBlocks, 100),
37
+ setTimeout(checkBlocks, 300),
38
+ setTimeout(checkBlocks, 500),
39
+ setTimeout(checkBlocks, 1000),
40
+ ];
41
+ return () => {
42
+ clearInterval(interval);
43
+ timeouts.forEach(clearTimeout);
44
+ };
45
+ }, [registeredBlocks.length]);
46
+ return registeredBlocks;
47
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Hook for managing unsaved changes warnings and auto-save
3
+ */
4
+ import type { EditorState } from '../../../state/types';
5
+ import type { Block } from '../../../types/block';
6
+ interface UseUnsavedChangesOptions {
7
+ state: EditorState;
8
+ isDirty: boolean;
9
+ onSave: (heroBlock?: Block | null) => Promise<void>;
10
+ heroBlock?: Block | null;
11
+ autoSaveEnabled?: boolean;
12
+ autoSaveDelay?: number;
13
+ postId?: string | null;
14
+ }
15
+ /**
16
+ * Hook to manage unsaved changes warnings and auto-save
17
+ */
18
+ export declare function useUnsavedChanges({ state, isDirty, onSave, heroBlock, autoSaveEnabled: propAutoSaveEnabled, autoSaveDelay, postId, }: UseUnsavedChangesOptions): {
19
+ autoSaveEnabled: boolean;
20
+ setAutoSaveEnabled: (enabled: boolean) => void;
21
+ countdown: number | null;
22
+ saveStatus: "error" | "idle" | "saving" | "saved";
23
+ };
24
+ export {};
25
+ //# sourceMappingURL=useUnsavedChanges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUnsavedChanges.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/useUnsavedChanges.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAElD,UAAU,wBAAwB;IAC9B,KAAK,EAAE,WAAW,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,SAAS,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAKD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAC9B,KAAK,EACL,OAAO,EACP,MAAM,EACN,SAAS,EACT,eAAe,EAAE,mBAAmB,EACpC,aAAuC,EACvC,MAAM,GACT,EAAE,wBAAwB;;kCAoD6B,OAAO;;;EA4P9D"}
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Hook for managing unsaved changes warnings and auto-save
3
+ */
4
+ 'use client';
5
+ import { useEffect, useRef, useCallback, useState } from 'react';
6
+ const AUTO_SAVE_STORAGE_KEY = 'blog-editor-autosave-enabled';
7
+ const DEFAULT_AUTO_SAVE_DELAY = 10000; // 10 seconds
8
+ /**
9
+ * Hook to manage unsaved changes warnings and auto-save
10
+ */
11
+ export function useUnsavedChanges({ state, isDirty, onSave, heroBlock, autoSaveEnabled: propAutoSaveEnabled, autoSaveDelay = DEFAULT_AUTO_SAVE_DELAY, postId, }) {
12
+ const autoSaveTimeoutRef = useRef(null);
13
+ const isSavingRef = useRef(false);
14
+ const lastSavedStateRef = useRef('');
15
+ const countdownIntervalRef = useRef(null);
16
+ const [countdown, setCountdown] = useState(null);
17
+ const [saveStatus, setSaveStatus] = useState('idle');
18
+ const saveStatusTimeoutRef = useRef(null);
19
+ const previousIsDirtyRef = useRef(false);
20
+ const countdownStartTimeRef = useRef(null);
21
+ const performAutoSaveRef = useRef(null);
22
+ // Get auto-save preference from localStorage
23
+ const getAutoSavePreference = useCallback(() => {
24
+ if (typeof window === 'undefined')
25
+ return false;
26
+ try {
27
+ const stored = localStorage.getItem(AUTO_SAVE_STORAGE_KEY);
28
+ if (stored !== null) {
29
+ return stored === 'true';
30
+ }
31
+ }
32
+ catch (error) {
33
+ console.error('[useUnsavedChanges] Failed to read auto-save preference:', error);
34
+ }
35
+ // Default to false if not set
36
+ return false;
37
+ }, []);
38
+ // State to track auto-save enabled status (reactive)
39
+ const [autoSaveEnabledState, setAutoSaveEnabledState] = useState(() => {
40
+ // Initialize from prop or localStorage
41
+ if (propAutoSaveEnabled !== undefined) {
42
+ return propAutoSaveEnabled;
43
+ }
44
+ return getAutoSavePreference();
45
+ });
46
+ // Sync with prop changes
47
+ useEffect(() => {
48
+ if (propAutoSaveEnabled !== undefined) {
49
+ setAutoSaveEnabledState(propAutoSaveEnabled);
50
+ }
51
+ }, [propAutoSaveEnabled]);
52
+ // Initialize from localStorage on mount (if no prop provided)
53
+ useEffect(() => {
54
+ if (propAutoSaveEnabled === undefined && typeof window !== 'undefined') {
55
+ const stored = getAutoSavePreference();
56
+ setAutoSaveEnabledState(stored);
57
+ }
58
+ }, []); // Only run on mount
59
+ // Set auto-save preference in localStorage and state
60
+ const setAutoSavePreference = useCallback((enabled) => {
61
+ if (typeof window === 'undefined')
62
+ return;
63
+ try {
64
+ localStorage.setItem(AUTO_SAVE_STORAGE_KEY, enabled.toString());
65
+ setAutoSaveEnabledState(enabled);
66
+ console.log('[useUnsavedChanges] Auto-save preference updated:', enabled);
67
+ }
68
+ catch (error) {
69
+ console.error('[useUnsavedChanges] Failed to save auto-save preference:', error);
70
+ }
71
+ }, []);
72
+ // Determine if auto-save is enabled (prop takes precedence over state)
73
+ const autoSaveEnabled = propAutoSaveEnabled !== undefined
74
+ ? propAutoSaveEnabled
75
+ : autoSaveEnabledState;
76
+ // Create a stable reference of the current state for comparison
77
+ const getStateSnapshot = useCallback(() => {
78
+ return JSON.stringify({
79
+ title: state.title,
80
+ slug: state.slug,
81
+ blocks: state.blocks,
82
+ seo: state.seo,
83
+ metadata: state.metadata,
84
+ status: state.status,
85
+ });
86
+ }, [state]);
87
+ // Initialize lastSavedStateRef when a post is loaded and marked as clean
88
+ useEffect(() => {
89
+ // When a post is loaded (postId exists) and isDirty is false, update the saved state reference
90
+ if (postId && !isDirty && lastSavedStateRef.current === '') {
91
+ lastSavedStateRef.current = getStateSnapshot();
92
+ console.log('[useUnsavedChanges] Initialized saved state reference after post load');
93
+ }
94
+ // Also update if isDirty becomes false after being true (e.g., after save or MARK_CLEAN)
95
+ if (!isDirty && lastSavedStateRef.current !== getStateSnapshot()) {
96
+ lastSavedStateRef.current = getStateSnapshot();
97
+ }
98
+ }, [postId, isDirty, getStateSnapshot]);
99
+ // Auto-save function
100
+ const performAutoSave = useCallback(async () => {
101
+ if (isSavingRef.current || !isDirty) {
102
+ return;
103
+ }
104
+ try {
105
+ isSavingRef.current = true;
106
+ setSaveStatus('saving');
107
+ setCountdown(null);
108
+ countdownStartTimeRef.current = null;
109
+ console.log('[useUnsavedChanges] Auto-saving...');
110
+ await onSave(heroBlock);
111
+ lastSavedStateRef.current = getStateSnapshot();
112
+ setSaveStatus('saved');
113
+ console.log('[useUnsavedChanges] Auto-save completed');
114
+ // Clear save status after 2 seconds
115
+ if (saveStatusTimeoutRef.current) {
116
+ clearTimeout(saveStatusTimeoutRef.current);
117
+ }
118
+ saveStatusTimeoutRef.current = setTimeout(() => {
119
+ setSaveStatus('idle');
120
+ }, 2000);
121
+ }
122
+ catch (error) {
123
+ console.error('[useUnsavedChanges] Auto-save failed:', error);
124
+ setSaveStatus('error');
125
+ // Clear error status after 3 seconds
126
+ if (saveStatusTimeoutRef.current) {
127
+ clearTimeout(saveStatusTimeoutRef.current);
128
+ }
129
+ saveStatusTimeoutRef.current = setTimeout(() => {
130
+ setSaveStatus('idle');
131
+ }, 3000);
132
+ }
133
+ finally {
134
+ isSavingRef.current = false;
135
+ }
136
+ }, [isDirty, onSave, heroBlock, getStateSnapshot]);
137
+ // Keep ref updated with latest function
138
+ useEffect(() => {
139
+ performAutoSaveRef.current = performAutoSave;
140
+ }, [performAutoSave]);
141
+ // Set up auto-save timer and countdown when state changes
142
+ useEffect(() => {
143
+ // Only reset countdown if isDirty changed from false to true, or if auto-save was just disabled
144
+ const isDirtyChanged = previousIsDirtyRef.current !== isDirty;
145
+ const becameDirty = !previousIsDirtyRef.current && isDirty;
146
+ // Update previous isDirty ref
147
+ previousIsDirtyRef.current = isDirty;
148
+ // Clear existing countdown interval
149
+ if (countdownIntervalRef.current) {
150
+ clearInterval(countdownIntervalRef.current);
151
+ countdownIntervalRef.current = null;
152
+ }
153
+ if (!autoSaveEnabled || !isDirty || isSavingRef.current) {
154
+ setCountdown(null);
155
+ countdownStartTimeRef.current = null;
156
+ // Clear timeout if auto-save is disabled or not dirty
157
+ if (autoSaveTimeoutRef.current) {
158
+ clearTimeout(autoSaveTimeoutRef.current);
159
+ autoSaveTimeoutRef.current = null;
160
+ }
161
+ return;
162
+ }
163
+ // Only reset countdown if:
164
+ // 1. isDirty just became true (new changes)
165
+ // 2. Or if there's no active countdown
166
+ const shouldResetCountdown = becameDirty || countdownStartTimeRef.current === null;
167
+ if (shouldResetCountdown) {
168
+ // Clear existing timeout
169
+ if (autoSaveTimeoutRef.current) {
170
+ clearTimeout(autoSaveTimeoutRef.current);
171
+ }
172
+ // Initialize countdown
173
+ const secondsRemaining = Math.ceil(autoSaveDelay / 1000);
174
+ setCountdown(secondsRemaining);
175
+ countdownStartTimeRef.current = Date.now();
176
+ // Set new timeout for auto-save
177
+ autoSaveTimeoutRef.current = setTimeout(() => {
178
+ if (performAutoSaveRef.current) {
179
+ performAutoSaveRef.current();
180
+ }
181
+ }, autoSaveDelay);
182
+ }
183
+ else {
184
+ // Countdown is already running, just update it based on elapsed time
185
+ if (countdownStartTimeRef.current && autoSaveTimeoutRef.current) {
186
+ const elapsed = Date.now() - countdownStartTimeRef.current;
187
+ const remaining = Math.max(0, autoSaveDelay - elapsed);
188
+ const secondsRemaining = Math.ceil(remaining / 1000);
189
+ setCountdown(secondsRemaining);
190
+ }
191
+ }
192
+ // Update countdown every second (only if we have an active countdown)
193
+ if (shouldResetCountdown || countdownIntervalRef.current === null) {
194
+ countdownIntervalRef.current = setInterval(() => {
195
+ if (countdownStartTimeRef.current && autoSaveTimeoutRef.current) {
196
+ const elapsed = Date.now() - countdownStartTimeRef.current;
197
+ const remaining = Math.max(0, autoSaveDelay - elapsed);
198
+ const secondsRemaining = Math.ceil(remaining / 1000);
199
+ if (secondsRemaining <= 0) {
200
+ setCountdown(null);
201
+ if (countdownIntervalRef.current) {
202
+ clearInterval(countdownIntervalRef.current);
203
+ countdownIntervalRef.current = null;
204
+ }
205
+ }
206
+ else {
207
+ setCountdown(secondsRemaining);
208
+ }
209
+ }
210
+ }, 1000);
211
+ }
212
+ return () => {
213
+ if (autoSaveTimeoutRef.current) {
214
+ clearTimeout(autoSaveTimeoutRef.current);
215
+ }
216
+ if (countdownIntervalRef.current) {
217
+ clearInterval(countdownIntervalRef.current);
218
+ }
219
+ };
220
+ }, [autoSaveEnabled, isDirty, autoSaveDelay]);
221
+ // Handle browser beforeunload event (page refresh/close)
222
+ useEffect(() => {
223
+ if (!isDirty) {
224
+ return;
225
+ }
226
+ const handleBeforeUnload = (e) => {
227
+ e.preventDefault();
228
+ // Modern browsers ignore custom messages, but we still need to set returnValue
229
+ e.returnValue = '';
230
+ return '';
231
+ };
232
+ window.addEventListener('beforeunload', handleBeforeUnload);
233
+ return () => {
234
+ window.removeEventListener('beforeunload', handleBeforeUnload);
235
+ };
236
+ }, [isDirty]);
237
+ // Handle link clicks (for Next.js App Router)
238
+ useEffect(() => {
239
+ if (!isDirty) {
240
+ return;
241
+ }
242
+ const handleLinkClick = (e) => {
243
+ const target = e.target;
244
+ const link = target.closest('a');
245
+ if (link && link.href) {
246
+ const url = new URL(link.href);
247
+ const currentPath = window.location.pathname;
248
+ // Check if navigating away from editor
249
+ if (!url.pathname.includes('/blog/editor') && !url.pathname.includes('/blog/new')) {
250
+ const confirmed = window.confirm('You have unsaved changes. Are you sure you want to leave? Your changes will be lost.');
251
+ if (!confirmed) {
252
+ e.preventDefault();
253
+ e.stopPropagation();
254
+ return false;
255
+ }
256
+ }
257
+ }
258
+ };
259
+ // Listen for clicks on links
260
+ document.addEventListener('click', handleLinkClick, true);
261
+ return () => {
262
+ document.removeEventListener('click', handleLinkClick, true);
263
+ };
264
+ }, [isDirty]);
265
+ // Cleanup on unmount
266
+ useEffect(() => {
267
+ return () => {
268
+ if (autoSaveTimeoutRef.current) {
269
+ clearTimeout(autoSaveTimeoutRef.current);
270
+ }
271
+ if (countdownIntervalRef.current) {
272
+ clearInterval(countdownIntervalRef.current);
273
+ }
274
+ if (saveStatusTimeoutRef.current) {
275
+ clearTimeout(saveStatusTimeoutRef.current);
276
+ }
277
+ };
278
+ }, []);
279
+ return {
280
+ autoSaveEnabled,
281
+ setAutoSaveEnabled: setAutoSavePreference,
282
+ countdown,
283
+ saveStatus,
284
+ };
285
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Canvas Editor View Exports
3
+ */
4
+ export { CanvasEditorView } from './CanvasEditorView';
5
+ export type { CanvasEditorViewProps } from './CanvasEditorView';
6
+ export { EditorBody } from './EditorBody';
7
+ export { LayoutContainer } from './LayoutContainer';
8
+ export type { LayoutContainerProps } from './LayoutContainer';
9
+ export type { EditorBodyProps } from './EditorBody';
10
+ export { BlockWrapper } from './BlockWrapper';
11
+ export type { BlockWrapperProps } from './BlockWrapper';
12
+ export { EditorHeader } from './EditorHeader';
13
+ export type { EditorHeaderProps } from './EditorHeader';
14
+ export { SaveConfirmationModal } from './SaveConfirmationModal';
15
+ export type { SaveConfirmationModalProps } from './SaveConfirmationModal';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Canvas Editor View Exports
3
+ */
4
+ export { CanvasEditorView } from './CanvasEditorView';
5
+ export { EditorBody } from './EditorBody';
6
+ export { LayoutContainer } from './LayoutContainer';
7
+ export { BlockWrapper } from './BlockWrapper';
8
+ export { EditorHeader } from './EditorHeader';
9
+ export { SaveConfirmationModal } from './SaveConfirmationModal';