@jhits/plugin-blog 0.0.8 → 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.
- package/dist/api/categories.d.ts +8 -0
- package/dist/api/categories.d.ts.map +1 -0
- package/dist/api/categories.js +30 -0
- package/dist/api/check-title.d.ts +8 -0
- package/dist/api/check-title.d.ts.map +1 -0
- package/dist/api/check-title.js +47 -0
- package/dist/api/config-handler.d.ts +21 -0
- package/dist/api/config-handler.d.ts.map +1 -0
- package/dist/api/config-handler.js +46 -0
- package/dist/api/handler.d.ts +42 -0
- package/dist/api/handler.d.ts.map +1 -0
- package/dist/api/handler.js +331 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +12 -0
- package/dist/api/route.d.ts +50 -0
- package/dist/api/route.d.ts.map +1 -0
- package/dist/api/route.js +69 -0
- package/dist/api/router.d.ts +27 -0
- package/dist/api/router.d.ts.map +1 -0
- package/dist/api/router.js +98 -0
- package/dist/api-server.d.ts +9 -0
- package/dist/api-server.d.ts.map +1 -0
- package/dist/api-server.js +9 -0
- package/dist/config.d.ts +14 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +156 -0
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/useBlog.d.ts +31 -0
- package/dist/hooks/useBlog.d.ts.map +1 -0
- package/dist/hooks/useBlog.js +57 -0
- package/dist/hooks/useBlogs.d.ts +39 -0
- package/dist/hooks/useBlogs.d.ts.map +1 -0
- package/dist/hooks/useBlogs.js +82 -0
- package/dist/hooks/useCategories.d.ts +9 -0
- package/dist/hooks/useCategories.d.ts.map +1 -0
- package/dist/hooks/useCategories.js +70 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +228 -0
- package/dist/index.server.d.ts +12 -0
- package/dist/index.server.d.ts.map +1 -0
- package/dist/index.server.js +10 -0
- package/dist/init.d.ts +40 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +41 -0
- package/dist/lib/blocks/BlockRenderer.d.ts +54 -0
- package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -0
- package/dist/lib/blocks/BlockRenderer.js +54 -0
- package/dist/lib/blocks/index.d.ts +5 -0
- package/dist/lib/blocks/index.d.ts.map +1 -0
- package/dist/lib/blocks/index.js +4 -0
- package/dist/lib/config-storage.d.ts +30 -0
- package/dist/lib/config-storage.d.ts.map +1 -0
- package/dist/lib/config-storage.js +31 -0
- package/dist/lib/index.d.ts +8 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +7 -0
- package/dist/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
- package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
- package/dist/lib/layouts/blocks/ColumnsBlock.js +186 -0
- package/dist/lib/layouts/blocks/SectionBlock.d.ts +25 -0
- package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
- package/dist/lib/layouts/blocks/SectionBlock.js +44 -0
- package/dist/lib/layouts/blocks/index.d.ts +7 -0
- package/dist/lib/layouts/blocks/index.d.ts.map +1 -0
- package/dist/lib/layouts/blocks/index.js +6 -0
- package/dist/lib/layouts/index.d.ts +23 -0
- package/dist/lib/layouts/index.d.ts.map +1 -0
- package/dist/lib/layouts/index.js +45 -0
- package/dist/lib/layouts/registerLayoutBlocks.d.ts +9 -0
- package/dist/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
- package/dist/lib/layouts/registerLayoutBlocks.js +60 -0
- package/dist/lib/mappers/apiMapper.d.ts +66 -0
- package/dist/lib/mappers/apiMapper.d.ts.map +1 -0
- package/dist/lib/mappers/apiMapper.js +188 -0
- package/dist/lib/migration/index.d.ts +5 -0
- package/dist/lib/migration/index.d.ts.map +1 -0
- package/dist/lib/migration/index.js +4 -0
- package/dist/lib/migration/mapper.d.ts +37 -0
- package/dist/lib/migration/mapper.d.ts.map +1 -0
- package/dist/lib/migration/mapper.js +98 -0
- package/dist/lib/rich-text/RichTextEditor.d.ts +45 -0
- package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -0
- package/dist/lib/rich-text/RichTextEditor.js +556 -0
- package/dist/lib/rich-text/RichTextPreview.d.ts +16 -0
- package/dist/lib/rich-text/RichTextPreview.d.ts.map +1 -0
- package/dist/lib/rich-text/RichTextPreview.js +144 -0
- package/dist/lib/rich-text/index.d.ts +9 -0
- package/dist/lib/rich-text/index.d.ts.map +1 -0
- package/dist/lib/rich-text/index.js +6 -0
- package/dist/lib/utils/blockHelpers.d.ts +23 -0
- package/dist/lib/utils/blockHelpers.d.ts.map +1 -0
- package/dist/lib/utils/blockHelpers.js +65 -0
- package/dist/lib/utils/configValidation.d.ts +23 -0
- package/dist/lib/utils/configValidation.d.ts.map +1 -0
- package/dist/lib/utils/configValidation.js +111 -0
- package/dist/lib/utils/index.d.ts +7 -0
- package/dist/lib/utils/index.d.ts.map +1 -0
- package/dist/lib/utils/index.js +6 -0
- package/dist/lib/utils/slugify.d.ts +25 -0
- package/dist/lib/utils/slugify.d.ts.map +1 -0
- package/dist/lib/utils/slugify.js +65 -0
- package/dist/registry/BlockRegistry.d.ts +62 -0
- package/dist/registry/BlockRegistry.d.ts.map +1 -0
- package/dist/registry/BlockRegistry.js +112 -0
- package/dist/registry/index.d.ts +6 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +4 -0
- package/dist/state/EditorContext.d.ts +45 -0
- package/dist/state/EditorContext.d.ts.map +1 -0
- package/dist/state/EditorContext.js +215 -0
- package/dist/state/index.d.ts +7 -0
- package/dist/state/index.d.ts.map +1 -0
- package/dist/state/index.js +6 -0
- package/dist/state/reducer.d.ts +11 -0
- package/dist/state/reducer.d.ts.map +1 -0
- package/dist/state/reducer.js +599 -0
- package/dist/state/types.d.ts +162 -0
- package/dist/state/types.d.ts.map +1 -0
- package/dist/state/types.js +27 -0
- package/dist/types/block.d.ts +221 -0
- package/dist/types/block.d.ts.map +1 -0
- package/dist/types/block.js +6 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/post.d.ts +136 -0
- package/dist/types/post.d.ts.map +1 -0
- package/dist/types/post.js +5 -0
- package/dist/utils/client.d.ts +48 -0
- package/dist/utils/client.d.ts.map +1 -0
- package/dist/utils/client.js +77 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -0
- package/dist/views/CanvasEditor/BlockWrapper.d.ts +16 -0
- package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
- package/dist/views/CanvasEditor/BlockWrapper.js +285 -0
- package/dist/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
- package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
- package/dist/views/CanvasEditor/CanvasEditorView.js +215 -0
- package/dist/views/CanvasEditor/EditorBody.d.ts +22 -0
- package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -0
- package/dist/views/CanvasEditor/EditorBody.js +505 -0
- package/dist/views/CanvasEditor/EditorHeader.d.ts +18 -0
- package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
- package/dist/views/CanvasEditor/EditorHeader.js +101 -0
- package/dist/views/CanvasEditor/LayoutContainer.d.ts +17 -0
- package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
- package/dist/views/CanvasEditor/LayoutContainer.js +222 -0
- package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
- package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
- package/dist/views/CanvasEditor/SaveConfirmationModal.js +78 -0
- package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
- package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/CustomBlockItem.js +44 -0
- package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
- package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/EditorCanvas.js +32 -0
- package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
- package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/EditorLibrary.js +25 -0
- package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
- package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/EditorSidebar.js +19 -0
- package/dist/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
- package/dist/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/ErrorBanner.js +8 -0
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +199 -0
- package/dist/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
- package/dist/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/LibraryItem.js +43 -0
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +70 -0
- package/dist/views/CanvasEditor/components/index.d.ts +21 -0
- package/dist/views/CanvasEditor/components/index.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/index.js +12 -0
- package/dist/views/CanvasEditor/hooks/index.d.ts +10 -0
- package/dist/views/CanvasEditor/hooks/index.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/index.js +9 -0
- package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
- package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/useHeroBlock.js +90 -0
- package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
- package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.js +119 -0
- package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
- package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/usePostLoader.js +32 -0
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
- package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
- package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
- package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
- package/dist/views/CanvasEditor/index.d.ts +16 -0
- package/dist/views/CanvasEditor/index.d.ts.map +1 -0
- package/dist/views/CanvasEditor/index.js +9 -0
- package/dist/views/PostManager/EmptyState.d.ts +10 -0
- package/dist/views/PostManager/EmptyState.d.ts.map +1 -0
- package/dist/views/PostManager/EmptyState.js +12 -0
- package/dist/views/PostManager/PostActionsMenu.d.ts +12 -0
- package/dist/views/PostManager/PostActionsMenu.d.ts.map +1 -0
- package/dist/views/PostManager/PostActionsMenu.js +58 -0
- package/dist/views/PostManager/PostCards.d.ts +15 -0
- package/dist/views/PostManager/PostCards.d.ts.map +1 -0
- package/dist/views/PostManager/PostCards.js +77 -0
- package/dist/views/PostManager/PostFilters.d.ts +16 -0
- package/dist/views/PostManager/PostFilters.d.ts.map +1 -0
- package/dist/views/PostManager/PostFilters.js +10 -0
- package/dist/views/PostManager/PostManagerView.d.ts +11 -0
- package/dist/views/PostManager/PostManagerView.d.ts.map +1 -0
- package/dist/views/PostManager/PostManagerView.js +179 -0
- package/dist/views/PostManager/PostStats.d.ts +11 -0
- package/dist/views/PostManager/PostStats.d.ts.map +1 -0
- package/dist/views/PostManager/PostStats.js +46 -0
- package/dist/views/PostManager/PostTable.d.ts +15 -0
- package/dist/views/PostManager/PostTable.d.ts.map +1 -0
- package/dist/views/PostManager/PostTable.js +77 -0
- package/dist/views/PostManager/index.d.ts +12 -0
- package/dist/views/PostManager/index.d.ts.map +1 -0
- package/dist/views/PostManager/index.js +11 -0
- package/dist/views/Preview/PreviewBridgeView.d.ts +12 -0
- package/dist/views/Preview/PreviewBridgeView.d.ts.map +1 -0
- package/dist/views/Preview/PreviewBridgeView.js +11 -0
- package/dist/views/Preview/index.d.ts +6 -0
- package/dist/views/Preview/index.d.ts.map +1 -0
- package/dist/views/Preview/index.js +4 -0
- package/dist/views/Settings/SettingsView.d.ts +10 -0
- package/dist/views/Settings/SettingsView.d.ts.map +1 -0
- package/dist/views/Settings/SettingsView.js +113 -0
- package/dist/views/Settings/index.d.ts +6 -0
- package/dist/views/Settings/index.d.ts.map +1 -0
- package/dist/views/Settings/index.js +4 -0
- package/dist/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
- package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
- package/dist/views/SlugSEO/SlugSEOManagerView.js +11 -0
- package/dist/views/SlugSEO/index.d.ts +6 -0
- package/dist/views/SlugSEO/index.d.ts.map +1 -0
- package/dist/views/SlugSEO/index.js +4 -0
- package/package.json +59 -59
- package/src/hooks/index.d.ts +8 -0
- package/src/hooks/index.d.ts.map +1 -0
- package/src/hooks/index.js +7 -0
- package/src/hooks/useBlog.d.ts +31 -0
- package/src/hooks/useBlog.d.ts.map +1 -0
- package/src/hooks/useBlog.js +57 -0
- package/src/hooks/useBlogs.d.ts +39 -0
- package/src/hooks/useBlogs.d.ts.map +1 -0
- package/src/hooks/useBlogs.js +82 -0
- package/src/hooks/useCategories.d.ts +9 -0
- package/src/hooks/useCategories.d.ts.map +1 -0
- package/src/hooks/useCategories.js +70 -0
- package/src/index.d.ts +55 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +228 -0
- package/src/init.d.ts +40 -0
- package/src/init.d.ts.map +1 -0
- package/src/init.js +41 -0
- package/src/lib/blocks/BlockRenderer.d.ts +54 -0
- package/src/lib/blocks/BlockRenderer.d.ts.map +1 -0
- package/src/lib/blocks/BlockRenderer.js +54 -0
- package/src/lib/config-storage.d.ts +30 -0
- package/src/lib/config-storage.d.ts.map +1 -0
- package/src/lib/config-storage.js +31 -0
- package/src/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
- package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
- package/src/lib/layouts/blocks/ColumnsBlock.js +182 -0
- package/src/lib/layouts/blocks/SectionBlock.d.ts +25 -0
- package/src/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
- package/src/lib/layouts/blocks/SectionBlock.js +44 -0
- package/src/lib/layouts/index.d.ts +23 -0
- package/src/lib/layouts/index.d.ts.map +1 -0
- package/src/lib/layouts/index.js +45 -0
- package/src/lib/layouts/registerLayoutBlocks.d.ts +9 -0
- package/src/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
- package/src/lib/layouts/registerLayoutBlocks.js +60 -0
- package/src/lib/mappers/apiMapper.d.ts +66 -0
- package/src/lib/mappers/apiMapper.d.ts.map +1 -0
- package/src/lib/mappers/apiMapper.js +191 -0
- package/src/lib/rich-text/RichTextEditor.d.ts +45 -0
- package/src/lib/rich-text/RichTextEditor.d.ts.map +1 -0
- package/src/lib/rich-text/RichTextEditor.js +564 -0
- package/src/lib/rich-text/RichTextPreview.d.ts +16 -0
- package/src/lib/rich-text/RichTextPreview.d.ts.map +1 -0
- package/src/lib/rich-text/RichTextPreview.js +144 -0
- package/src/lib/rich-text/index.d.ts +9 -0
- package/src/lib/rich-text/index.d.ts.map +1 -0
- package/src/lib/rich-text/index.js +6 -0
- package/src/lib/utils/blockHelpers.d.ts +23 -0
- package/src/lib/utils/blockHelpers.d.ts.map +1 -0
- package/src/lib/utils/blockHelpers.js +65 -0
- package/src/lib/utils/configValidation.d.ts +23 -0
- package/src/lib/utils/configValidation.d.ts.map +1 -0
- package/src/lib/utils/configValidation.js +113 -0
- package/src/registry/BlockRegistry.d.ts +62 -0
- package/src/registry/BlockRegistry.d.ts.map +1 -0
- package/src/registry/BlockRegistry.js +112 -0
- package/src/registry/index.d.ts +6 -0
- package/src/registry/index.d.ts.map +1 -0
- package/src/registry/index.js +4 -0
- package/src/state/EditorContext.d.ts +45 -0
- package/src/state/EditorContext.d.ts.map +1 -0
- package/src/state/EditorContext.js +215 -0
- package/src/state/index.d.ts +7 -0
- package/src/state/index.d.ts.map +1 -0
- package/src/state/index.js +6 -0
- package/src/state/reducer.d.ts +11 -0
- package/src/state/reducer.d.ts.map +1 -0
- package/src/state/reducer.js +443 -0
- package/src/state/types.d.ts +162 -0
- package/src/state/types.d.ts.map +1 -0
- package/src/state/types.js +27 -0
- package/src/types/block.d.ts +221 -0
- package/src/types/block.d.ts.map +1 -0
- package/src/types/block.js +6 -0
- package/src/types/index.d.ts +8 -0
- package/src/types/index.d.ts.map +1 -0
- package/src/types/index.js +5 -0
- package/src/types/post.d.ts +136 -0
- package/src/types/post.d.ts.map +1 -0
- package/src/types/post.js +5 -0
- package/src/utils/client.d.ts +48 -0
- package/src/utils/client.d.ts.map +1 -0
- package/src/utils/client.js +77 -0
- package/src/views/CanvasEditor/BlockWrapper.d.ts +16 -0
- package/src/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
- package/src/views/CanvasEditor/BlockWrapper.js +276 -0
- package/src/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
- package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
- package/src/views/CanvasEditor/CanvasEditorView.js +209 -0
- package/src/views/CanvasEditor/EditorBody.d.ts +22 -0
- package/src/views/CanvasEditor/EditorBody.d.ts.map +1 -0
- package/src/views/CanvasEditor/EditorBody.js +505 -0
- package/src/views/CanvasEditor/EditorHeader.d.ts +18 -0
- package/src/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
- package/src/views/CanvasEditor/EditorHeader.js +101 -0
- package/src/views/CanvasEditor/LayoutContainer.d.ts +17 -0
- package/src/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
- package/src/views/CanvasEditor/LayoutContainer.js +222 -0
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
- package/src/views/CanvasEditor/SaveConfirmationModal.js +78 -0
- package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
- package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/CustomBlockItem.js +44 -0
- package/src/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
- package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/EditorCanvas.js +32 -0
- package/src/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
- package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/EditorLibrary.js +25 -0
- package/src/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
- package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/EditorSidebar.js +20 -0
- package/src/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
- package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/ErrorBanner.js +8 -0
- package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
- package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/FeaturedMediaSection.js +182 -0
- package/src/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
- package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/LibraryItem.js +43 -0
- package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
- package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/PrivacySettingsSection.js +63 -0
- package/src/views/CanvasEditor/components/index.d.ts +21 -0
- package/src/views/CanvasEditor/components/index.d.ts.map +1 -0
- package/src/views/CanvasEditor/components/index.js +12 -0
- package/src/views/CanvasEditor/hooks/index.d.ts +10 -0
- package/src/views/CanvasEditor/hooks/index.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/index.js +9 -0
- package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
- package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/useHeroBlock.js +79 -0
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.js +114 -0
- package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
- package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/usePostLoader.js +32 -0
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
- package/src/views/CanvasEditor/index.d.ts +16 -0
- package/src/views/CanvasEditor/index.d.ts.map +1 -0
- package/src/views/CanvasEditor/index.js +9 -0
- package/src/views/PostManager/EmptyState.d.ts +10 -0
- package/src/views/PostManager/EmptyState.d.ts.map +1 -0
- package/src/views/PostManager/EmptyState.js +12 -0
- package/src/views/PostManager/PostActionsMenu.d.ts +12 -0
- package/src/views/PostManager/PostActionsMenu.d.ts.map +1 -0
- package/src/views/PostManager/PostActionsMenu.js +58 -0
- package/src/views/PostManager/PostCards.d.ts +15 -0
- package/src/views/PostManager/PostCards.d.ts.map +1 -0
- package/src/views/PostManager/PostCards.js +79 -0
- package/src/views/PostManager/PostFilters.d.ts +16 -0
- package/src/views/PostManager/PostFilters.d.ts.map +1 -0
- package/src/views/PostManager/PostFilters.js +10 -0
- package/src/views/PostManager/PostManagerView.d.ts +11 -0
- package/src/views/PostManager/PostManagerView.d.ts.map +1 -0
- package/src/views/PostManager/PostManagerView.js +174 -0
- package/src/views/PostManager/PostStats.d.ts +11 -0
- package/src/views/PostManager/PostStats.d.ts.map +1 -0
- package/src/views/PostManager/PostStats.js +46 -0
- package/src/views/PostManager/PostTable.d.ts +15 -0
- package/src/views/PostManager/PostTable.d.ts.map +1 -0
- package/src/views/PostManager/PostTable.js +79 -0
- package/src/views/PostManager/index.d.ts +12 -0
- package/src/views/PostManager/index.d.ts.map +1 -0
- package/src/views/PostManager/index.js +11 -0
- package/src/views/Preview/PreviewBridgeView.d.ts +12 -0
- package/src/views/Preview/PreviewBridgeView.d.ts.map +1 -0
- package/src/views/Preview/PreviewBridgeView.js +11 -0
- package/src/views/Preview/index.d.ts +6 -0
- package/src/views/Preview/index.d.ts.map +1 -0
- package/src/views/Preview/index.js +4 -0
- package/src/views/Settings/SettingsView.d.ts +10 -0
- package/src/views/Settings/SettingsView.d.ts.map +1 -0
- package/src/views/Settings/SettingsView.js +111 -0
- package/src/views/Settings/index.d.ts +6 -0
- package/src/views/Settings/index.d.ts.map +1 -0
- package/src/views/Settings/index.js +4 -0
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
- package/src/views/SlugSEO/SlugSEOManagerView.js +11 -0
- package/src/views/SlugSEO/index.d.ts +6 -0
- package/src/views/SlugSEO/index.d.ts.map +1 -0
- package/src/views/SlugSEO/index.js +4 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { ArrowLeft, Library, Settings2, Clock, Edit, Eye } from 'lucide-react';
|
|
5
|
+
import { useEditor } from '../../state/EditorContext';
|
|
6
|
+
import { SaveConfirmationModal } from './SaveConfirmationModal';
|
|
7
|
+
export function EditorHeader({ isLibraryOpen, onLibraryToggle, isPreviewMode, onPreviewToggle, isSidebarOpen, onSidebarToggle, isSaving, onSave, onSaveError, autoSaveEnabled = false, onAutoSaveToggle, isDirty = false, autoSaveCountdown = null, autoSaveStatus = 'idle', }) {
|
|
8
|
+
const { state, dispatch } = useEditor();
|
|
9
|
+
const [showConfirmModal, setShowConfirmModal] = useState(false);
|
|
10
|
+
const [saveAsDraft, setSaveAsDraft] = useState(false);
|
|
11
|
+
const [saveError, setSaveError] = useState(null);
|
|
12
|
+
const handleSaveDraftClick = () => {
|
|
13
|
+
setSaveAsDraft(true);
|
|
14
|
+
setSaveError(null); // Clear any previous errors
|
|
15
|
+
setShowConfirmModal(true);
|
|
16
|
+
};
|
|
17
|
+
const handlePublishClick = () => {
|
|
18
|
+
setSaveAsDraft(false);
|
|
19
|
+
setSaveError(null); // Clear any previous errors
|
|
20
|
+
setShowConfirmModal(true);
|
|
21
|
+
};
|
|
22
|
+
const handleConfirmSave = async () => {
|
|
23
|
+
try {
|
|
24
|
+
const targetStatus = saveAsDraft ? 'draft' : 'published';
|
|
25
|
+
console.log('[EditorHeader] Starting save process...', { saveAsDraft, targetStatus, currentStatus: state.status });
|
|
26
|
+
// Set status before saving - ensure state is updated
|
|
27
|
+
if (saveAsDraft) {
|
|
28
|
+
dispatch({ type: 'SET_STATUS', payload: 'draft' });
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
dispatch({ type: 'SET_STATUS', payload: 'published' });
|
|
32
|
+
}
|
|
33
|
+
// Wait longer to ensure state update propagates through the reducer and context
|
|
34
|
+
// React state updates are asynchronous, so we need to wait for the state to actually update
|
|
35
|
+
await new Promise(resolve => setTimeout(resolve, 150));
|
|
36
|
+
// Verify status was updated
|
|
37
|
+
console.log('[EditorHeader] Status after update:', state.status, 'Expected:', targetStatus);
|
|
38
|
+
await onSave(!saveAsDraft);
|
|
39
|
+
console.log('[EditorHeader] Post saved successfully');
|
|
40
|
+
// Clear any previous errors
|
|
41
|
+
setSaveError(null);
|
|
42
|
+
// Modal will show success message and close automatically
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error('[EditorHeader] Failed to save post:', error);
|
|
46
|
+
// Extract user-friendly error message
|
|
47
|
+
let errorMessage = error.message || 'Failed to save post';
|
|
48
|
+
// Make error messages more user-friendly
|
|
49
|
+
if (errorMessage.includes('Missing required fields')) {
|
|
50
|
+
// Keep the detailed message about missing fields
|
|
51
|
+
errorMessage = errorMessage.replace('Missing required fields for publishing:', 'To publish, please fill in:');
|
|
52
|
+
}
|
|
53
|
+
else if (errorMessage.includes('All required fields')) {
|
|
54
|
+
errorMessage = 'To publish, please fill in all required fields: summary, featured image, category, and content.';
|
|
55
|
+
}
|
|
56
|
+
else if (errorMessage.includes('Unauthorized')) {
|
|
57
|
+
errorMessage = 'You are not authorized to save this post. Please log in again.';
|
|
58
|
+
}
|
|
59
|
+
else if (errorMessage.includes('Failed to save')) {
|
|
60
|
+
errorMessage = 'Unable to save the post. Please check your connection and try again.';
|
|
61
|
+
}
|
|
62
|
+
setSaveError(errorMessage);
|
|
63
|
+
onSaveError(errorMessage);
|
|
64
|
+
// Re-throw the error so the modal knows it failed and doesn't show success
|
|
65
|
+
throw error;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
return (_jsxs("header", { className: "flex items-center justify-between px-6 py-3 bg-dashboard-sidebar backdrop-blur-md border-b border-dashboard-border flex-none shrink-0", children: [_jsxs("div", { className: "flex items-center gap-6", children: [_jsx("button", { onClick: () => {
|
|
69
|
+
if (isDirty) {
|
|
70
|
+
const confirmed = window.confirm('You have unsaved changes. Are you sure you want to leave? Your changes will be lost.');
|
|
71
|
+
if (!confirmed) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
window.location.href = '/dashboard/blog';
|
|
76
|
+
}, className: "text-neutral-500 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white transition-colors", children: _jsx(ArrowLeft, { size: 20, strokeWidth: 1.5 }) }), _jsx("div", { className: "h-4 w-[1px] bg-neutral-300 dark:border-neutral-700" }), _jsxs("button", { onClick: onLibraryToggle, className: `flex items-center gap-2 text-[10px] uppercase tracking-widest font-black transition-all ${isLibraryOpen ? 'text-dashboard-text' : 'text-neutral-500 dark:text-neutral-400'}`, children: [_jsx(Library, { size: 16, strokeWidth: 1.5 }), "Library"] })] }), _jsxs("div", { className: "flex items-center gap-4", children: [onAutoSaveToggle && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { onClick: () => onAutoSaveToggle(!autoSaveEnabled), className: `relative flex items-center gap-2 px-3 py-1.5 rounded-full text-[10px] uppercase tracking-widest font-bold transition-all ${autoSaveEnabled
|
|
77
|
+
? 'bg-primary/20 text-primary border border-primary/30'
|
|
78
|
+
: 'bg-dashboard-bg text-neutral-600 dark:text-neutral-400 border border-dashboard-border hover:text-neutral-950 dark:hover:text-white'}`, title: autoSaveEnabled ? 'Auto-save enabled (saves after 10s of inactivity)' : 'Click to enable auto-save', children: [_jsx(Clock, { size: 12, className: autoSaveEnabled && autoSaveStatus !== 'saving' ? 'animate-pulse' : '' }), _jsx("span", { children: "Auto-save" }), _jsx("span", { className: `ml-1 text-[9px] ${autoSaveEnabled ? 'text-primary' : 'text-neutral-500 dark:text-neutral-400'}`, children: autoSaveEnabled ? 'ON' : 'OFF' }), autoSaveEnabled && isDirty && (_jsxs("span", { className: "ml-1.5 text-[9px] font-bold tabular-nums", children: [autoSaveStatus === 'saving' && (_jsx("span", { className: "text-primary animate-pulse", children: "Saving..." })), autoSaveStatus === 'saved' && (_jsx("span", { className: "text-green-500 dark:text-green-400", children: "Saved!" })), autoSaveStatus === 'error' && (_jsx("span", { className: "text-red-500 dark:text-red-400", children: "Error" })), autoSaveStatus === 'idle' && autoSaveCountdown !== null && (_jsxs("span", { className: "text-primary/70", children: [autoSaveCountdown, "s"] }))] }))] }), isDirty && !autoSaveEnabled && (_jsx("span", { className: "text-[10px] text-amber-500 dark:text-amber-400 font-bold uppercase tracking-widest animate-pulse", children: "Unsaved" }))] })), _jsxs("div", { className: "flex items-center bg-dashboard-bg border border-dashboard-border rounded-full p-1 gap-1", children: [_jsxs("button", { onClick: () => {
|
|
79
|
+
if (isPreviewMode) {
|
|
80
|
+
onPreviewToggle();
|
|
81
|
+
}
|
|
82
|
+
}, className: `flex items-center gap-1.5 px-3 py-1.5 rounded-full text-[10px] uppercase tracking-widest font-bold transition-all ${!isPreviewMode
|
|
83
|
+
? 'bg-primary text-white shadow-sm'
|
|
84
|
+
: 'text-neutral-600 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'}`, title: "Edit mode - Make changes to your post", children: [_jsx(Edit, { size: 12, strokeWidth: 2.5 }), _jsx("span", { children: "Edit" })] }), _jsxs("button", { onClick: () => {
|
|
85
|
+
if (!isPreviewMode) {
|
|
86
|
+
onPreviewToggle();
|
|
87
|
+
}
|
|
88
|
+
}, className: `flex items-center gap-1.5 px-3 py-1.5 rounded-full text-[10px] uppercase tracking-widest font-bold transition-all ${isPreviewMode
|
|
89
|
+
? 'bg-primary text-white shadow-sm'
|
|
90
|
+
: 'text-neutral-600 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'}`, title: "Preview mode - See how your post will look", children: [_jsx(Eye, { size: 12, strokeWidth: 2.5 }), _jsx("span", { children: "Preview" })] })] }), (state.status === 'draft' || !state.postId) && (_jsx("button", { onClick: handleSaveDraftClick, disabled: isSaving, className: `px-4 py-2 border-2 border-dashboard-border text-dashboard-text rounded-full text-[10px] font-bold uppercase tracking-widest transition-all ${isSaving
|
|
91
|
+
? 'opacity-50 cursor-not-allowed'
|
|
92
|
+
: 'hover:bg-dashboard-bg'}`, children: isSaving ? 'Saving...' : 'Save Draft' })), _jsx("button", { onClick: handlePublishClick, disabled: isSaving, className: `px-6 py-2 bg-primary text-white rounded-full text-[10px] font-bold uppercase tracking-widest transition-all shadow-lg shadow-primary/20 ${isSaving
|
|
93
|
+
? 'opacity-50 cursor-not-allowed'
|
|
94
|
+
: 'hover:bg-primary/90'}`, children: isSaving ? 'Saving...' : state.status === 'published' ? 'Update Post' : 'Publish Post' }), _jsx("button", { onClick: onSidebarToggle, className: `p-2 rounded-full transition-colors ${isSidebarOpen
|
|
95
|
+
? 'bg-dashboard-bg text-dashboard-text'
|
|
96
|
+
: 'text-neutral-500 dark:text-neutral-400 hover:bg-dashboard-bg'}`, children: _jsx(Settings2, { size: 18 }) })] }), _jsx(SaveConfirmationModal, { isOpen: showConfirmModal, onClose: () => {
|
|
97
|
+
setShowConfirmModal(false);
|
|
98
|
+
setSaveAsDraft(false);
|
|
99
|
+
setSaveError(null);
|
|
100
|
+
}, onConfirm: handleConfirmSave, isSaving: isSaving, postTitle: state.title || undefined, isPublished: state.status === 'published', saveAsDraft: saveAsDraft, error: saveError })] }));
|
|
101
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Container Component
|
|
3
|
+
* Recursive drop zone for nested blocks
|
|
4
|
+
*/
|
|
5
|
+
import { Block } from '../../types/block';
|
|
6
|
+
export interface LayoutContainerProps {
|
|
7
|
+
blocks: Block[];
|
|
8
|
+
containerId: string;
|
|
9
|
+
onBlockAdd: (type: string, index: number, containerId: string) => void;
|
|
10
|
+
onBlockUpdate: (id: string, data: Partial<Block['data']>, containerId: string) => void;
|
|
11
|
+
onBlockDelete: (id: string, containerId: string) => void;
|
|
12
|
+
onBlockMove: (id: string, newIndex: number, containerId: string) => void;
|
|
13
|
+
className?: string;
|
|
14
|
+
emptyLabel?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function LayoutContainer({ blocks, containerId, onBlockAdd, onBlockUpdate, onBlockDelete, onBlockMove, className, emptyLabel, }: LayoutContainerProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=LayoutContainer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LayoutContainer.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/LayoutContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI1C,MAAM,WAAW,oBAAoB;IACjC,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACvE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACvF,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,eAAe,CAAC,EAC5B,MAAM,EACN,WAAW,EACX,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,SAAc,EACd,UAA+B,GAClC,EAAE,oBAAoB,2CA6OtB"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Layout Container Component
|
|
3
|
+
* Recursive drop zone for nested blocks
|
|
4
|
+
*/
|
|
5
|
+
'use client';
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
+
import { useState, useEffect, useRef } from 'react';
|
|
8
|
+
import { Plus } from 'lucide-react';
|
|
9
|
+
import { BlockWrapper } from './BlockWrapper';
|
|
10
|
+
import { useEditor } from '../../state/EditorContext';
|
|
11
|
+
export function LayoutContainer({ blocks, containerId, onBlockAdd, onBlockUpdate, onBlockDelete, onBlockMove, className = '', emptyLabel = 'Drop blocks here', }) {
|
|
12
|
+
const { darkMode } = useEditor();
|
|
13
|
+
// --- State ---
|
|
14
|
+
const [dragOverIndex, setDragOverIndex] = useState(null);
|
|
15
|
+
const [dropAtEnd, setDropAtEnd] = useState(false);
|
|
16
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
17
|
+
const [dropIndicatorPosition, setDropIndicatorPosition] = useState(null);
|
|
18
|
+
const containerRef = useRef(null);
|
|
19
|
+
const blockRefs = useRef(new Map());
|
|
20
|
+
// Use ref to ensure we always have the latest dropAtEnd value (React state updates are async)
|
|
21
|
+
const dropAtEndRef = useRef(false);
|
|
22
|
+
// --- Cleanup & Event Listeners ---
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const resetState = () => {
|
|
25
|
+
setDropIndicatorPosition(null);
|
|
26
|
+
setDragOverIndex(null);
|
|
27
|
+
setDropAtEnd(false);
|
|
28
|
+
dropAtEndRef.current = false; // Reset ref too
|
|
29
|
+
setIsDragging(false);
|
|
30
|
+
// Clear global dragged block ID on dragend (in case drag was cancelled)
|
|
31
|
+
if (typeof window !== 'undefined') {
|
|
32
|
+
window.__DRAGGED_BLOCK_ID__ = null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const container = containerRef.current;
|
|
36
|
+
if (container) {
|
|
37
|
+
container.addEventListener('clear-drop-indicator', resetState);
|
|
38
|
+
document.addEventListener('dragend', resetState);
|
|
39
|
+
return () => {
|
|
40
|
+
container.removeEventListener('clear-drop-indicator', resetState);
|
|
41
|
+
document.removeEventListener('dragend', resetState);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}, []);
|
|
45
|
+
// --- Drag & Drop Logic ---
|
|
46
|
+
const handleDragOverBlock = (e, index, element) => {
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
e.stopPropagation();
|
|
49
|
+
// 1. Check for deeper nested containers
|
|
50
|
+
const target = e.target;
|
|
51
|
+
const deeperContainer = target.closest('[data-layout-container]');
|
|
52
|
+
if (deeperContainer && deeperContainer !== containerRef.current) {
|
|
53
|
+
setDropIndicatorPosition(null);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
// 2. Notify parent containers to hide their indicators
|
|
57
|
+
e.currentTarget.dispatchEvent(new CustomEvent('clear-drop-indicator', { bubbles: true }));
|
|
58
|
+
// 3. Calculate "Above" vs "Below" and position indicator between blocks
|
|
59
|
+
const containerRect = containerRef.current.getBoundingClientRect();
|
|
60
|
+
const elementRect = element.getBoundingClientRect();
|
|
61
|
+
const mouseRelativeToBlock = e.clientY - elementRect.top;
|
|
62
|
+
const isBottomHalf = mouseRelativeToBlock > (elementRect.height / 2);
|
|
63
|
+
setDragOverIndex(index);
|
|
64
|
+
setDropAtEnd(isBottomHalf);
|
|
65
|
+
dropAtEndRef.current = isBottomHalf; // Update ref immediately
|
|
66
|
+
setIsDragging(true);
|
|
67
|
+
// 4. Update Visual Indicator - always show between blocks
|
|
68
|
+
const elementTop = elementRect.top - containerRect.top;
|
|
69
|
+
const elementBottom = elementRect.bottom - containerRect.top;
|
|
70
|
+
let indicatorTop;
|
|
71
|
+
if (isBottomHalf) {
|
|
72
|
+
// Show below this block - position between current block and next block
|
|
73
|
+
if (index === blocks.length - 1) {
|
|
74
|
+
// Last block - show after it
|
|
75
|
+
indicatorTop = elementBottom;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
// Get next block to find the gap
|
|
79
|
+
const nextBlock = blocks[index + 1];
|
|
80
|
+
const nextBlockEl = blockRefs.current.get(nextBlock.id);
|
|
81
|
+
if (nextBlockEl) {
|
|
82
|
+
const nextBlockRect = nextBlockEl.getBoundingClientRect();
|
|
83
|
+
const nextBlockTop = nextBlockRect.top - containerRect.top;
|
|
84
|
+
// Position in the middle of the gap (mb-4 = 16px margin)
|
|
85
|
+
indicatorTop = elementBottom + (nextBlockTop - elementBottom) / 2;
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
indicatorTop = elementBottom;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
// Show above this block - position between previous block and current block
|
|
94
|
+
if (index === 0) {
|
|
95
|
+
// First block - show at top of container (before first block)
|
|
96
|
+
indicatorTop = 0;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Get previous block to find the gap
|
|
100
|
+
const prevBlock = blocks[index - 1];
|
|
101
|
+
const prevBlockEl = blockRefs.current.get(prevBlock.id);
|
|
102
|
+
if (prevBlockEl) {
|
|
103
|
+
const prevBlockRect = prevBlockEl.getBoundingClientRect();
|
|
104
|
+
const prevBlockBottom = prevBlockRect.bottom - containerRect.top;
|
|
105
|
+
// Position in the middle of the gap (mb-4 = 16px margin)
|
|
106
|
+
indicatorTop = prevBlockBottom + (elementTop - prevBlockBottom) / 2;
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
indicatorTop = elementTop;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
setDropIndicatorPosition({
|
|
114
|
+
top: indicatorTop,
|
|
115
|
+
left: 0,
|
|
116
|
+
width: containerRect.width,
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
const handleDrop = (e, index) => {
|
|
120
|
+
e.preventDefault();
|
|
121
|
+
e.stopPropagation();
|
|
122
|
+
const blockId = e.dataTransfer.getData('block-id') || window.__DRAGGED_BLOCK_ID__;
|
|
123
|
+
const blockType = e.dataTransfer.getData('block-type');
|
|
124
|
+
// Clear the global dragged block ID immediately to prevent it from being used for new blocks
|
|
125
|
+
if (typeof window !== 'undefined') {
|
|
126
|
+
window.__DRAGGED_BLOCK_ID__ = null;
|
|
127
|
+
}
|
|
128
|
+
// Logic: index is null when dropping on the container background (appends to end)
|
|
129
|
+
// When dropAtEnd is true, we want to place it AFTER the block at index, so targetIndex = index + 1
|
|
130
|
+
// When dropAtEnd is false, we want to place it BEFORE the block at index, so targetIndex = index
|
|
131
|
+
// Use ref to get the latest value (React state updates are async)
|
|
132
|
+
const isDropAtEnd = dropAtEndRef.current;
|
|
133
|
+
let targetIndex = index === null ? blocks.length : (isDropAtEnd ? index + 1 : index);
|
|
134
|
+
if (blockId) {
|
|
135
|
+
const currentIndex = blocks.findIndex(b => b.id === blockId);
|
|
136
|
+
if (currentIndex !== -1) {
|
|
137
|
+
// Moving within the same array - need to adjust for removal
|
|
138
|
+
let finalMoveIndex = targetIndex;
|
|
139
|
+
if (currentIndex < targetIndex) {
|
|
140
|
+
// Moving forward: when we remove the item from currentIndex, everything after it shifts down by 1.
|
|
141
|
+
if (isDropAtEnd) {
|
|
142
|
+
// Dropping below: we want it at index + 1 in the original array
|
|
143
|
+
// If currentIndex <= index: after removal, block at index stays at index, so we want index + 1 = targetIndex
|
|
144
|
+
// If index < currentIndex < targetIndex: after removal, we still want index + 1, but since we removed
|
|
145
|
+
// an item before targetIndex, the position targetIndex in original = targetIndex - 1 in new array
|
|
146
|
+
if (index !== null && currentIndex <= index) {
|
|
147
|
+
// Item is at or before target block - no adjustment needed
|
|
148
|
+
finalMoveIndex = targetIndex;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
// Item is after target block but before targetIndex - need to adjust
|
|
152
|
+
finalMoveIndex = targetIndex - 1;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// Dropping above: targetIndex = index means "before the block at index"
|
|
157
|
+
// After removal, if currentIndex < index, the block at index shifts to index - 1,
|
|
158
|
+
// so we want it at index - 1 in the new array.
|
|
159
|
+
finalMoveIndex = targetIndex - 1;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// If currentIndex >= targetIndex, no adjustment needed (moving backward or same position)
|
|
163
|
+
console.log('[LayoutContainer] Drop calculation:', {
|
|
164
|
+
blockId,
|
|
165
|
+
index,
|
|
166
|
+
dropAtEnd: isDropAtEnd,
|
|
167
|
+
currentIndex,
|
|
168
|
+
targetIndex,
|
|
169
|
+
finalMoveIndex,
|
|
170
|
+
blocksCount: blocks.length
|
|
171
|
+
});
|
|
172
|
+
onBlockMove(blockId, Math.max(0, finalMoveIndex), containerId);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Moving from another container - no adjustment needed
|
|
176
|
+
onBlockMove(blockId, targetIndex, containerId);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else if (blockType) {
|
|
180
|
+
// Adding new block - use targetIndex as-is
|
|
181
|
+
onBlockAdd(blockType, targetIndex, containerId);
|
|
182
|
+
}
|
|
183
|
+
// Clean up
|
|
184
|
+
setDropIndicatorPosition(null);
|
|
185
|
+
setDragOverIndex(null);
|
|
186
|
+
setDropAtEnd(false);
|
|
187
|
+
};
|
|
188
|
+
const setBlockRef = (id) => (el) => {
|
|
189
|
+
if (el)
|
|
190
|
+
blockRefs.current.set(id, el);
|
|
191
|
+
else
|
|
192
|
+
blockRefs.current.delete(id);
|
|
193
|
+
};
|
|
194
|
+
return (_jsxs("div", { ref: containerRef, "data-layout-container": containerId, className: `relative flex flex-col min-h-[40px] transition-colors ${className}`, onDragOver: (e) => { e.preventDefault(); setIsDragging(true); }, onDrop: (e) => handleDrop(e, null), onDragLeave: (e) => {
|
|
195
|
+
if (!e.currentTarget.contains(e.relatedTarget)) {
|
|
196
|
+
setDropIndicatorPosition(null);
|
|
197
|
+
}
|
|
198
|
+
}, children: [dropIndicatorPosition && isDragging && (_jsx(DropIndicator, { position: dropIndicatorPosition, darkMode: darkMode })), blocks.length === 0 ? (_jsx(EmptyState, { isDragging: isDragging, darkMode: darkMode, label: emptyLabel })) : (blocks.map((block, index) => (_jsx("div", { ref: setBlockRef(block.id), onDragOver: (e) => handleDragOverBlock(e, index, blockRefs.current.get(block.id)), onDrop: (e) => handleDrop(e, index), className: "relative mb-4 last:mb-0", children: _jsx(BlockWrapper, { block: block, onUpdate: (data) => onBlockUpdate(block.id, data, containerId), onDelete: () => onBlockDelete(block.id, containerId), onMoveUp: index > 0 ? () => onBlockMove(block.id, index - 1, containerId) : undefined, onMoveDown: index < blocks.length - 1 ? () => onBlockMove(block.id, index + 1, containerId) : undefined }) }, block.id))))] }));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Visual Line that shows where the block will land
|
|
202
|
+
*/
|
|
203
|
+
function DropIndicator({ position, darkMode }) {
|
|
204
|
+
return (_jsxs("div", { className: "absolute z-50 pointer-events-none", style: {
|
|
205
|
+
top: `${position.top - 12}px`,
|
|
206
|
+
left: `${position.left}px`,
|
|
207
|
+
width: `${position.width}px`,
|
|
208
|
+
height: '24px',
|
|
209
|
+
}, children: [_jsx("div", { className: `absolute inset-0 rounded-lg border border-dashed backdrop-blur-sm
|
|
210
|
+
${darkMode ? 'bg-primary/20 border-primary/40' : 'bg-primary/10 border-primary/30'}` }), _jsx("div", { className: `absolute top-1/2 left-0 right-0 h-0.5 transform -translate-y-1/2
|
|
211
|
+
${darkMode ? 'bg-primary' : 'bg-primary'}` }), _jsx("div", { className: "absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2", children: _jsx("div", { className: "w-6 h-6 rounded-full flex items-center justify-center bg-primary shadow-lg", children: _jsx("div", { className: "w-2 h-2 rounded-full bg-white" }) }) })] }));
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Placeholder when the container is empty
|
|
215
|
+
*/
|
|
216
|
+
function EmptyState({ isDragging, darkMode, label }) {
|
|
217
|
+
return (_jsxs("div", { className: `flex flex-col items-center justify-center py-12 px-6 rounded-2xl border border-dashed transition-all
|
|
218
|
+
${darkMode
|
|
219
|
+
? isDragging ? 'border-primary/50 bg-primary/10' : 'border-neutral-700 bg-neutral-800/20'
|
|
220
|
+
: isDragging ? 'border-primary/50 bg-primary/5' : 'border-neutral-200 bg-neutral-50/30'}`, children: [_jsx("div", { className: `p-3 rounded-full mb-3 ${darkMode ? 'bg-neutral-800' : 'bg-neutral-100'}`, children: _jsx(Plus, { size: 20, className: isDragging ? 'text-primary' : 'text-neutral-400' }) }), _jsx("p", { className: `text-xs font-black uppercase tracking-wider
|
|
221
|
+
${isDragging ? 'text-primary' : 'text-neutral-500'}`, children: isDragging ? 'Drop Block Here' : label })] }));
|
|
222
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface SaveConfirmationModalProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
onConfirm: () => Promise<void>;
|
|
6
|
+
isSaving: boolean;
|
|
7
|
+
postTitle?: string;
|
|
8
|
+
isPublished?: boolean;
|
|
9
|
+
saveAsDraft?: boolean;
|
|
10
|
+
error?: string | null;
|
|
11
|
+
}
|
|
12
|
+
export declare function SaveConfirmationModal({ isOpen, onClose, onConfirm, isSaving, postTitle, isPublished, saveAsDraft, error, }: SaveConfirmationModalProps): React.ReactPortal | null;
|
|
13
|
+
//# sourceMappingURL=SaveConfirmationModal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SaveConfirmationModal.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/SaveConfirmationModal.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,MAAM,WAAW,0BAA0B;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAED,wBAAgB,qBAAqB,CAAC,EAClC,MAAM,EACN,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAS,EACT,WAAW,EACX,WAAmB,EACnB,KAAK,GACR,EAAE,0BAA0B,4BA4M5B"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { X, AlertTriangle, CheckCircle2 } from 'lucide-react';
|
|
6
|
+
import { motion, AnimatePresence } from 'framer-motion';
|
|
7
|
+
export function SaveConfirmationModal({ isOpen, onClose, onConfirm, isSaving, postTitle, isPublished, saveAsDraft = false, error, }) {
|
|
8
|
+
const [mounted, setMounted] = useState(false);
|
|
9
|
+
const [showSuccess, setShowSuccess] = useState(false);
|
|
10
|
+
const [saveError, setSaveError] = useState(null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
setMounted(true);
|
|
13
|
+
}, []);
|
|
14
|
+
// Reset states when modal opens
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (isOpen) {
|
|
17
|
+
setShowSuccess(false);
|
|
18
|
+
setSaveError(null);
|
|
19
|
+
}
|
|
20
|
+
}, [isOpen]);
|
|
21
|
+
// Update error state when error prop changes
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (error) {
|
|
24
|
+
setSaveError(error);
|
|
25
|
+
setShowSuccess(false);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
setSaveError(null);
|
|
29
|
+
}
|
|
30
|
+
}, [error]);
|
|
31
|
+
if (!mounted)
|
|
32
|
+
return null;
|
|
33
|
+
const handleConfirm = async () => {
|
|
34
|
+
// Clear any previous errors
|
|
35
|
+
setSaveError(null);
|
|
36
|
+
try {
|
|
37
|
+
await onConfirm();
|
|
38
|
+
// Only show success if onConfirm completes without error
|
|
39
|
+
setShowSuccess(true);
|
|
40
|
+
// Close modal after showing success for 1.5 seconds
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
onClose();
|
|
43
|
+
setShowSuccess(false);
|
|
44
|
+
setSaveError(null);
|
|
45
|
+
}, 1500);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// Display error in modal
|
|
49
|
+
const errorMessage = error.message || 'Failed to save post. Please try again.';
|
|
50
|
+
setSaveError(errorMessage);
|
|
51
|
+
console.error('[SaveConfirmationModal] Save failed:', error);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const modalContent = (_jsx(AnimatePresence, { children: isOpen && (_jsxs("div", { className: "fixed inset-0 z-[9999] flex items-center justify-center p-4", children: [_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, exit: { opacity: 0 }, onClick: onClose, className: "absolute inset-0 bg-black/60 backdrop-blur-md" }), _jsxs(motion.div, { initial: { scale: 0.9, opacity: 0, y: 20 }, animate: { scale: 1, opacity: 1, y: 0 }, exit: { scale: 0.9, opacity: 0, y: 20 }, onClick: (e) => e.stopPropagation(), className: "relative w-full font-sans max-w-md bg-dashboard-card rounded-[2.5rem] p-8 shadow-2xl border border-dashboard-border", children: [_jsx("button", { onClick: onClose, disabled: isSaving, className: "absolute top-6 right-6 text-neutral-400 hover:text-neutral-900 dark:hover:text-white transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: _jsx(X, { size: 24 }) }), _jsx("div", { className: `w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-6 transition-all ${saveError
|
|
55
|
+
? 'bg-red-100 dark:bg-red-900/20'
|
|
56
|
+
: showSuccess
|
|
57
|
+
? 'bg-green-100 dark:bg-green-900/20'
|
|
58
|
+
: 'bg-amber-100 dark:bg-amber-900/20'}`, children: saveError ? (_jsx(AlertTriangle, { size: 32, className: "text-red-600 dark:text-red-400" })) : showSuccess ? (_jsx(CheckCircle2, { size: 32, className: "text-green-600 dark:text-green-400" })) : (_jsx(AlertTriangle, { size: 32, className: "text-amber-600 dark:text-amber-400" })) }), _jsx("h3", { className: "text-2xl font-black text-center mb-4 text-neutral-950 dark:text-white", children: saveError
|
|
59
|
+
? 'Error'
|
|
60
|
+
: showSuccess
|
|
61
|
+
? 'Success!'
|
|
62
|
+
: saveAsDraft
|
|
63
|
+
? 'Save Draft'
|
|
64
|
+
: `Confirm ${isPublished ? 'Update' : 'Publish'}` }), _jsx("div", { className: "text-center mb-8", children: saveError ? (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-red-700 dark:text-red-300 font-semibold", children: saveError }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: "Please fix the issues above and try again." })] })) : showSuccess ? (_jsx("p", { className: "text-green-700 dark:text-green-300 font-semibold", children: saveAsDraft ? 'Draft saved successfully!' : 'Post saved successfully!' })) : (_jsxs(_Fragment, { children: [_jsx("p", { className: "text-neutral-700 dark:text-neutral-300 mb-2", children: saveAsDraft
|
|
65
|
+
? 'Save this post as a draft? You can continue editing and publish it later.'
|
|
66
|
+
: isPublished
|
|
67
|
+
? 'You are about to update this post. Changes cannot be undone.'
|
|
68
|
+
: 'You are about to publish this post. This action cannot be undone.' }), postTitle && (_jsxs("p", { className: "text-sm text-neutral-500 dark:text-neutral-400 italic", children: ["\"", postTitle, "\""] }))] })) }), showSuccess ? (_jsx("div", { className: "flex justify-center", children: _jsx("button", { onClick: onClose, className: "px-6 py-3 rounded-full bg-green-600 text-white font-bold uppercase text-[10px] tracking-widest transition-all hover:bg-green-700 shadow-lg shadow-green-600/20", children: "Close" }) })) : saveError ? (_jsxs("div", { className: "flex gap-4", children: [_jsx("button", { onClick: onClose, className: "flex-1 px-6 py-3 rounded-full border-2 border-dashboard-border text-dashboard-text font-bold uppercase text-[10px] tracking-widest transition-all hover:bg-dashboard-bg", children: "Close" }), _jsx("button", { onClick: handleConfirm, disabled: isSaving, className: "flex-1 px-6 py-3 rounded-full bg-primary text-white font-bold uppercase text-[10px] tracking-widest transition-all hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg shadow-primary/20", children: isSaving
|
|
69
|
+
? 'Retrying...'
|
|
70
|
+
: 'Try Again' })] })) : (_jsxs("div", { className: "flex gap-4", children: [_jsx("button", { onClick: onClose, disabled: isSaving, className: "flex-1 px-6 py-3 rounded-full border-2 border-dashboard-border text-dashboard-text font-bold uppercase text-[10px] tracking-widest transition-all hover:bg-dashboard-bg disabled:opacity-50 disabled:cursor-not-allowed", children: "Cancel" }), _jsx("button", { onClick: handleConfirm, disabled: isSaving, className: "flex-1 px-6 py-3 rounded-full bg-primary text-white font-bold uppercase text-[10px] tracking-widest transition-all hover:bg-primary/90 disabled:opacity-50 disabled:cursor-not-allowed shadow-lg shadow-primary/20", children: isSaving
|
|
71
|
+
? 'Saving...'
|
|
72
|
+
: saveAsDraft
|
|
73
|
+
? 'Save Draft'
|
|
74
|
+
: isPublished
|
|
75
|
+
? 'Update Post'
|
|
76
|
+
: 'Publish Post' })] }))] })] })) }));
|
|
77
|
+
return createPortal(modalContent, document.body);
|
|
78
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface CustomBlockItemProps {
|
|
3
|
+
blockType: string;
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
icon: React.ReactNode;
|
|
7
|
+
onAddBlock?: (blockType: string) => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Custom Block Item Component
|
|
11
|
+
* Draggable custom block from client registry and clickable to add at bottom
|
|
12
|
+
*/
|
|
13
|
+
export declare function CustomBlockItem({ blockType, name, description, icon, onAddBlock }: CustomBlockItemProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=CustomBlockItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CustomBlockItem.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/CustomBlockItem.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAGhD,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAC5B,SAAS,EACT,IAAI,EACJ,WAAW,EACX,IAAI,EACJ,UAAU,EACb,EAAE,oBAAoB,2CAmEtB"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useRef } from 'react';
|
|
4
|
+
import { GripVertical } from 'lucide-react';
|
|
5
|
+
/**
|
|
6
|
+
* Custom Block Item Component
|
|
7
|
+
* Draggable custom block from client registry and clickable to add at bottom
|
|
8
|
+
*/
|
|
9
|
+
export function CustomBlockItem({ blockType, name, description, icon, onAddBlock }) {
|
|
10
|
+
const [hasDragged, setHasDragged] = useState(false);
|
|
11
|
+
const mouseDownRef = useRef(null);
|
|
12
|
+
const handleDragStart = (e) => {
|
|
13
|
+
e.dataTransfer.setData('block-type', blockType);
|
|
14
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
15
|
+
setHasDragged(true); // Mark as dragged when drag starts
|
|
16
|
+
};
|
|
17
|
+
const handleMouseDown = (e) => {
|
|
18
|
+
// Track mouse position on mousedown
|
|
19
|
+
mouseDownRef.current = { x: e.clientX, y: e.clientY };
|
|
20
|
+
setHasDragged(false); // Reset drag state
|
|
21
|
+
};
|
|
22
|
+
const handleMouseMove = (e) => {
|
|
23
|
+
// If mouse moved more than 5px, consider it a drag
|
|
24
|
+
if (mouseDownRef.current) {
|
|
25
|
+
const dx = Math.abs(e.clientX - mouseDownRef.current.x);
|
|
26
|
+
const dy = Math.abs(e.clientY - mouseDownRef.current.y);
|
|
27
|
+
if (dx > 5 || dy > 5) {
|
|
28
|
+
setHasDragged(true);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const handleClick = (e) => {
|
|
33
|
+
// Only add block if we didn't drag
|
|
34
|
+
if (!hasDragged && onAddBlock) {
|
|
35
|
+
e.preventDefault();
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
onAddBlock(blockType);
|
|
38
|
+
}
|
|
39
|
+
// Reset state
|
|
40
|
+
mouseDownRef.current = null;
|
|
41
|
+
setTimeout(() => setHasDragged(false), 100);
|
|
42
|
+
};
|
|
43
|
+
return (_jsxs("div", { draggable: true, onDragStart: handleDragStart, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onClick: handleClick, className: "p-4 rounded-xl border border-dashboard-border bg-dashboard-bg hover:border-primary cursor-pointer transition-all group", title: description, children: [_jsxs("div", { className: "flex items-center justify-between mb-2", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "text-neutral-500 dark:text-neutral-400 group-hover:text-primary dark:group-hover:text-primary transition-colors", children: icon }), _jsx("span", { className: "text-[10px] font-bold uppercase tracking-wider text-neutral-700 dark:text-neutral-300 group-hover:text-neutral-950 dark:group-hover:text-white transition-colors", children: name })] }), _jsx(GripVertical, { size: 12, className: "text-neutral-400 dark:text-neutral-500 group-hover:text-neutral-600 dark:group-hover:text-neutral-400" })] }), description && (_jsx("p", { className: "text-[9px] text-neutral-500 dark:text-neutral-400 leading-relaxed line-clamp-2", children: description }))] }));
|
|
44
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Block } from '../../../types/block';
|
|
2
|
+
import type { BlockTypeDefinition } from '../../../types/block';
|
|
3
|
+
export interface EditorCanvasProps {
|
|
4
|
+
isPreviewMode: boolean;
|
|
5
|
+
heroBlock: Block | null;
|
|
6
|
+
heroBlockDefinition: BlockTypeDefinition | undefined;
|
|
7
|
+
contentBlocks: Block[];
|
|
8
|
+
title: string;
|
|
9
|
+
siteId: string;
|
|
10
|
+
locale: string;
|
|
11
|
+
darkMode: boolean;
|
|
12
|
+
backgroundColors?: {
|
|
13
|
+
light: string;
|
|
14
|
+
dark?: string;
|
|
15
|
+
};
|
|
16
|
+
featuredImage?: {
|
|
17
|
+
id?: string;
|
|
18
|
+
alt?: string;
|
|
19
|
+
};
|
|
20
|
+
onTitleChange: (title: string) => void;
|
|
21
|
+
onHeroBlockUpdate: (data: Partial<Block['data']>) => void;
|
|
22
|
+
onHeroBlockDelete: () => void;
|
|
23
|
+
onBlockAdd: (type: string, index: number, containerId?: string) => void;
|
|
24
|
+
onBlockUpdate: (id: string, data: Partial<Block['data']>) => void;
|
|
25
|
+
onBlockDelete: (id: string) => void;
|
|
26
|
+
onBlockMove: (id: string, newIndex: number, containerId?: string) => void;
|
|
27
|
+
}
|
|
28
|
+
export declare function EditorCanvas({ isPreviewMode, heroBlock, heroBlockDefinition, contentBlocks, title, siteId, locale, darkMode, backgroundColors, featuredImage, onTitleChange, onHeroBlockUpdate, onHeroBlockDelete, onBlockAdd, onBlockUpdate, onBlockDelete, onBlockMove, }: EditorCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
//# sourceMappingURL=EditorCanvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorCanvas.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,WAAW,iBAAiB;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC;IACxB,mBAAmB,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACrD,aAAa,EAAE,KAAK,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,aAAa,CAAC,EAAE;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IAC1D,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7E;AAED,wBAAgB,YAAY,CAAC,EACzB,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,KAAK,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,GACd,EAAE,iBAAiB,2CA0GnB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
import { BlockWrapper } from '../BlockWrapper';
|
|
5
|
+
import { EditorBody } from '../EditorBody';
|
|
6
|
+
import { BlockRenderer } from '../../../lib/blocks/BlockRenderer';
|
|
7
|
+
export function EditorCanvas({ isPreviewMode, heroBlock, heroBlockDefinition, contentBlocks, title, siteId, locale, darkMode, backgroundColors, featuredImage, onTitleChange, onHeroBlockUpdate, onHeroBlockDelete, onBlockAdd, onBlockUpdate, onBlockDelete, onBlockMove, }) {
|
|
8
|
+
const titleRef = useRef(null);
|
|
9
|
+
// Handle Title Auto-resize
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (titleRef.current) {
|
|
12
|
+
titleRef.current.style.height = 'auto';
|
|
13
|
+
titleRef.current.style.height = `${titleRef.current.scrollHeight}px`;
|
|
14
|
+
}
|
|
15
|
+
}, [title]);
|
|
16
|
+
return (_jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden pb-40 px-6 custom-scrollbar selection:bg-primary/20 dark:selection:bg-primary/30 min-h-0", style: {
|
|
17
|
+
backgroundColor: backgroundColors
|
|
18
|
+
? (darkMode && backgroundColors.dark
|
|
19
|
+
? backgroundColors.dark
|
|
20
|
+
: backgroundColors.light)
|
|
21
|
+
: undefined,
|
|
22
|
+
}, children: _jsxs("div", { className: `mx-auto transition-all duration-500 max-w-7xl w-full`, children: [!isPreviewMode && heroBlockDefinition && heroBlock && (_jsx("div", { className: "mb-12", children: _jsx(BlockWrapper, { block: heroBlock, onUpdate: onHeroBlockUpdate, onDelete: onHeroBlockDelete, onMoveUp: () => { }, onMoveDown: () => { }, allBlocks: [heroBlock] }) })), isPreviewMode ? (_jsxs("div", { className: "space-y-8", children: [heroBlockDefinition && heroBlock && (_jsx(BlockRenderer, { block: heroBlock, context: {
|
|
23
|
+
siteId,
|
|
24
|
+
locale,
|
|
25
|
+
// Pass featured image as fallback for hero block
|
|
26
|
+
// Only pass id and alt - plugin-images handles transforms
|
|
27
|
+
fallbackImage: featuredImage ? {
|
|
28
|
+
id: featuredImage.id,
|
|
29
|
+
alt: featuredImage.alt,
|
|
30
|
+
} : undefined,
|
|
31
|
+
} })), !heroBlockDefinition && title && (_jsx("h1", { className: "text-5xl font-serif font-medium text-neutral-950 dark:text-white leading-tight mb-12", children: title })), contentBlocks.length > 0 ? (_jsx("div", { className: "space-y-8", children: contentBlocks.map((block) => (_jsx(BlockRenderer, { block: block, context: { siteId, locale } }, block.id))) })) : (_jsx("div", { className: "text-center py-20 text-neutral-400 dark:text-neutral-500", children: _jsx("p", { className: "text-sm", children: "No content blocks yet. Switch to Edit mode to add blocks." }) }))] })) : (_jsxs(_Fragment, { children: [!heroBlockDefinition && (_jsx("div", { className: "mb-12", children: _jsx("textarea", { ref: titleRef, rows: 1, value: title, onChange: (e) => onTitleChange(e.target.value), placeholder: "The title of your story...", className: "w-full bg-transparent border-none outline-none text-5xl font-serif font-medium placeholder:text-neutral-500 dark:placeholder:text-neutral-500 resize-none leading-tight transition-colors duration-300 text-neutral-950 dark:text-white" }) })), _jsx(EditorBody, { blocks: contentBlocks, darkMode: darkMode, backgroundColors: backgroundColors, onBlockAdd: onBlockAdd, onBlockUpdate: onBlockUpdate, onBlockDelete: onBlockDelete, onBlockMove: onBlockMove })] }))] }) }));
|
|
32
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { BlockTypeDefinition } from '../../../types/block';
|
|
2
|
+
export interface EditorLibraryProps {
|
|
3
|
+
registeredBlocks: BlockTypeDefinition[];
|
|
4
|
+
onAddBlock: (type: string) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function EditorLibrary({ registeredBlocks, onAddBlock }: EditorLibraryProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=EditorLibrary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditorLibrary.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorLibrary.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,MAAM,WAAW,kBAAkB;IAC/B,gBAAgB,EAAE,mBAAmB,EAAE,CAAC;IACxC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,aAAa,CAAC,EAAE,gBAAgB,EAAE,UAAU,EAAE,EAAE,kBAAkB,2CA6GjF"}
|