@jhits/plugin-blog 0.0.10 → 0.0.12
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/package.json +4 -5
- package/src/api/categories.ts +0 -43
- package/src/api/check-title.ts +0 -60
- package/src/api/config-handler.ts +0 -76
- package/src/api/handler.ts +0 -418
- package/src/api/index.ts +0 -33
- package/src/api/route.ts +0 -116
- package/src/api/router.ts +0 -128
- package/src/api-server.ts +0 -11
- package/src/config.ts +0 -161
- package/src/hooks/index.d.ts +0 -8
- package/src/hooks/index.d.ts.map +0 -1
- package/src/hooks/index.js +0 -7
- package/src/hooks/index.ts +0 -9
- package/src/hooks/useBlog.d.ts +0 -31
- package/src/hooks/useBlog.d.ts.map +0 -1
- package/src/hooks/useBlog.js +0 -57
- package/src/hooks/useBlog.ts +0 -85
- package/src/hooks/useBlogs.d.ts +0 -39
- package/src/hooks/useBlogs.d.ts.map +0 -1
- package/src/hooks/useBlogs.js +0 -82
- package/src/hooks/useBlogs.ts +0 -123
- package/src/hooks/useCategories.d.ts +0 -9
- package/src/hooks/useCategories.d.ts.map +0 -1
- package/src/hooks/useCategories.js +0 -70
- package/src/hooks/useCategories.ts +0 -76
- package/src/index.d.ts +0 -55
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -228
- package/src/index.server.ts +0 -14
- package/src/index.tsx +0 -335
- package/src/init.d.ts +0 -40
- package/src/init.d.ts.map +0 -1
- package/src/init.js +0 -41
- package/src/init.tsx +0 -63
- package/src/lib/blocks/BlockRenderer.d.ts +0 -54
- package/src/lib/blocks/BlockRenderer.d.ts.map +0 -1
- package/src/lib/blocks/BlockRenderer.js +0 -54
- package/src/lib/blocks/BlockRenderer.tsx +0 -141
- package/src/lib/blocks/index.ts +0 -6
- package/src/lib/config-storage.d.ts +0 -30
- package/src/lib/config-storage.d.ts.map +0 -1
- package/src/lib/config-storage.js +0 -31
- package/src/lib/config-storage.ts +0 -65
- package/src/lib/index.ts +0 -9
- package/src/lib/layouts/blocks/ColumnsBlock.d.ts +0 -25
- package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +0 -1
- package/src/lib/layouts/blocks/ColumnsBlock.js +0 -182
- package/src/lib/layouts/blocks/ColumnsBlock.tsx +0 -298
- package/src/lib/layouts/blocks/ColumnsBlock.tsx.tmp +0 -81
- package/src/lib/layouts/blocks/SectionBlock.d.ts +0 -25
- package/src/lib/layouts/blocks/SectionBlock.d.ts.map +0 -1
- package/src/lib/layouts/blocks/SectionBlock.js +0 -44
- package/src/lib/layouts/blocks/SectionBlock.tsx +0 -104
- package/src/lib/layouts/blocks/index.ts +0 -8
- package/src/lib/layouts/index.d.ts +0 -23
- package/src/lib/layouts/index.d.ts.map +0 -1
- package/src/lib/layouts/index.js +0 -45
- package/src/lib/layouts/index.ts +0 -52
- package/src/lib/layouts/registerLayoutBlocks.d.ts +0 -9
- package/src/lib/layouts/registerLayoutBlocks.d.ts.map +0 -1
- package/src/lib/layouts/registerLayoutBlocks.js +0 -60
- package/src/lib/layouts/registerLayoutBlocks.ts +0 -64
- package/src/lib/mappers/apiMapper.d.ts +0 -66
- package/src/lib/mappers/apiMapper.d.ts.map +0 -1
- package/src/lib/mappers/apiMapper.js +0 -191
- package/src/lib/mappers/apiMapper.ts +0 -254
- package/src/lib/migration/index.ts +0 -6
- package/src/lib/migration/mapper.ts +0 -140
- package/src/lib/rich-text/RichTextEditor.d.ts +0 -45
- package/src/lib/rich-text/RichTextEditor.d.ts.map +0 -1
- package/src/lib/rich-text/RichTextEditor.js +0 -564
- package/src/lib/rich-text/RichTextEditor.tsx +0 -826
- package/src/lib/rich-text/RichTextPreview.d.ts +0 -16
- package/src/lib/rich-text/RichTextPreview.d.ts.map +0 -1
- package/src/lib/rich-text/RichTextPreview.js +0 -144
- package/src/lib/rich-text/RichTextPreview.tsx +0 -210
- package/src/lib/rich-text/index.d.ts +0 -9
- package/src/lib/rich-text/index.d.ts.map +0 -1
- package/src/lib/rich-text/index.js +0 -6
- package/src/lib/rich-text/index.ts +0 -10
- package/src/lib/utils/blockHelpers.d.ts +0 -23
- package/src/lib/utils/blockHelpers.d.ts.map +0 -1
- package/src/lib/utils/blockHelpers.js +0 -65
- package/src/lib/utils/blockHelpers.ts +0 -72
- package/src/lib/utils/configValidation.d.ts +0 -23
- package/src/lib/utils/configValidation.d.ts.map +0 -1
- package/src/lib/utils/configValidation.js +0 -113
- package/src/lib/utils/configValidation.ts +0 -137
- package/src/lib/utils/index.ts +0 -8
- package/src/lib/utils/slugify.ts +0 -79
- package/src/registry/BlockRegistry.d.ts +0 -62
- package/src/registry/BlockRegistry.d.ts.map +0 -1
- package/src/registry/BlockRegistry.js +0 -112
- package/src/registry/BlockRegistry.ts +0 -139
- package/src/registry/index.d.ts +0 -6
- package/src/registry/index.d.ts.map +0 -1
- package/src/registry/index.js +0 -4
- package/src/registry/index.ts +0 -11
- package/src/state/EditorContext.d.ts +0 -45
- package/src/state/EditorContext.d.ts.map +0 -1
- package/src/state/EditorContext.js +0 -215
- package/src/state/EditorContext.tsx +0 -283
- package/src/state/index.d.ts +0 -7
- package/src/state/index.d.ts.map +0 -1
- package/src/state/index.js +0 -6
- package/src/state/index.ts +0 -8
- package/src/state/reducer.d.ts +0 -11
- package/src/state/reducer.d.ts.map +0 -1
- package/src/state/reducer.js +0 -443
- package/src/state/reducer.ts +0 -694
- package/src/state/types.d.ts +0 -162
- package/src/state/types.d.ts.map +0 -1
- package/src/state/types.js +0 -27
- package/src/state/types.ts +0 -160
- package/src/types/block.d.ts +0 -221
- package/src/types/block.d.ts.map +0 -1
- package/src/types/block.js +0 -6
- package/src/types/block.ts +0 -269
- package/src/types/index.d.ts +0 -8
- package/src/types/index.d.ts.map +0 -1
- package/src/types/index.js +0 -5
- package/src/types/index.ts +0 -17
- package/src/types/post.d.ts +0 -136
- package/src/types/post.d.ts.map +0 -1
- package/src/types/post.js +0 -5
- package/src/types/post.ts +0 -169
- package/src/utils/client.d.ts +0 -48
- package/src/utils/client.d.ts.map +0 -1
- package/src/utils/client.js +0 -77
- package/src/utils/client.ts +0 -122
- package/src/utils/index.ts +0 -7
- package/src/views/CanvasEditor/BlockWrapper.d.ts +0 -16
- package/src/views/CanvasEditor/BlockWrapper.d.ts.map +0 -1
- package/src/views/CanvasEditor/BlockWrapper.js +0 -276
- package/src/views/CanvasEditor/BlockWrapper.tsx +0 -522
- package/src/views/CanvasEditor/CanvasEditorView.d.ts +0 -14
- package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +0 -1
- package/src/views/CanvasEditor/CanvasEditorView.js +0 -209
- package/src/views/CanvasEditor/CanvasEditorView.tsx +0 -337
- package/src/views/CanvasEditor/EditorBody.d.ts +0 -22
- package/src/views/CanvasEditor/EditorBody.d.ts.map +0 -1
- package/src/views/CanvasEditor/EditorBody.js +0 -505
- package/src/views/CanvasEditor/EditorBody.tsx +0 -665
- package/src/views/CanvasEditor/EditorHeader.d.ts +0 -18
- package/src/views/CanvasEditor/EditorHeader.d.ts.map +0 -1
- package/src/views/CanvasEditor/EditorHeader.js +0 -101
- package/src/views/CanvasEditor/EditorHeader.tsx +0 -268
- package/src/views/CanvasEditor/LayoutContainer.d.ts +0 -17
- package/src/views/CanvasEditor/LayoutContainer.d.ts.map +0 -1
- package/src/views/CanvasEditor/LayoutContainer.js +0 -222
- package/src/views/CanvasEditor/LayoutContainer.tsx +0 -322
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +0 -13
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +0 -1
- package/src/views/CanvasEditor/SaveConfirmationModal.js +0 -78
- package/src/views/CanvasEditor/SaveConfirmationModal.tsx +0 -233
- package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +0 -14
- package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/CustomBlockItem.js +0 -44
- package/src/views/CanvasEditor/components/CustomBlockItem.tsx +0 -92
- package/src/views/CanvasEditor/components/EditorCanvas.d.ts +0 -29
- package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/EditorCanvas.js +0 -32
- package/src/views/CanvasEditor/components/EditorCanvas.tsx +0 -160
- package/src/views/CanvasEditor/components/EditorLibrary.d.ts +0 -7
- package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/EditorLibrary.js +0 -25
- package/src/views/CanvasEditor/components/EditorLibrary.tsx +0 -122
- package/src/views/CanvasEditor/components/EditorSidebar.d.ts +0 -13
- package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/EditorSidebar.js +0 -20
- package/src/views/CanvasEditor/components/EditorSidebar.tsx +0 -181
- package/src/views/CanvasEditor/components/ErrorBanner.d.ts +0 -6
- package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/ErrorBanner.js +0 -8
- package/src/views/CanvasEditor/components/ErrorBanner.tsx +0 -31
- package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -25
- package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/FeaturedMediaSection.js +0 -182
- package/src/views/CanvasEditor/components/FeaturedMediaSection.tsx +0 -341
- package/src/views/CanvasEditor/components/LibraryItem.d.ts +0 -14
- package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/LibraryItem.js +0 -43
- package/src/views/CanvasEditor/components/LibraryItem.tsx +0 -80
- package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -15
- package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/PrivacySettingsSection.js +0 -63
- package/src/views/CanvasEditor/components/PrivacySettingsSection.tsx +0 -212
- package/src/views/CanvasEditor/components/index.d.ts +0 -21
- package/src/views/CanvasEditor/components/index.d.ts.map +0 -1
- package/src/views/CanvasEditor/components/index.js +0 -12
- package/src/views/CanvasEditor/components/index.ts +0 -28
- package/src/views/CanvasEditor/hooks/index.d.ts +0 -10
- package/src/views/CanvasEditor/hooks/index.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/index.js +0 -9
- package/src/views/CanvasEditor/hooks/index.ts +0 -10
- package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +0 -8
- package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/useHeroBlock.js +0 -79
- package/src/views/CanvasEditor/hooks/useHeroBlock.ts +0 -103
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +0 -3
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.js +0 -114
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.ts +0 -142
- package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +0 -5
- package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/usePostLoader.js +0 -32
- package/src/views/CanvasEditor/hooks/usePostLoader.ts +0 -39
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +0 -2
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.js +0 -47
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.ts +0 -55
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +0 -25
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +0 -1
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.js +0 -285
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.ts +0 -339
- package/src/views/CanvasEditor/index.d.ts +0 -16
- package/src/views/CanvasEditor/index.d.ts.map +0 -1
- package/src/views/CanvasEditor/index.js +0 -9
- package/src/views/CanvasEditor/index.ts +0 -16
- package/src/views/PostManager/EmptyState.d.ts +0 -10
- package/src/views/PostManager/EmptyState.d.ts.map +0 -1
- package/src/views/PostManager/EmptyState.js +0 -12
- package/src/views/PostManager/EmptyState.tsx +0 -42
- package/src/views/PostManager/PostActionsMenu.d.ts +0 -12
- package/src/views/PostManager/PostActionsMenu.d.ts.map +0 -1
- package/src/views/PostManager/PostActionsMenu.js +0 -58
- package/src/views/PostManager/PostActionsMenu.tsx +0 -112
- package/src/views/PostManager/PostCards.d.ts +0 -15
- package/src/views/PostManager/PostCards.d.ts.map +0 -1
- package/src/views/PostManager/PostCards.js +0 -79
- package/src/views/PostManager/PostCards.tsx +0 -197
- package/src/views/PostManager/PostFilters.d.ts +0 -16
- package/src/views/PostManager/PostFilters.d.ts.map +0 -1
- package/src/views/PostManager/PostFilters.js +0 -10
- package/src/views/PostManager/PostFilters.tsx +0 -95
- package/src/views/PostManager/PostManagerView.d.ts +0 -11
- package/src/views/PostManager/PostManagerView.d.ts.map +0 -1
- package/src/views/PostManager/PostManagerView.js +0 -174
- package/src/views/PostManager/PostManagerView.tsx +0 -289
- package/src/views/PostManager/PostStats.d.ts +0 -11
- package/src/views/PostManager/PostStats.d.ts.map +0 -1
- package/src/views/PostManager/PostStats.js +0 -46
- package/src/views/PostManager/PostStats.tsx +0 -81
- package/src/views/PostManager/PostTable.d.ts +0 -15
- package/src/views/PostManager/PostTable.d.ts.map +0 -1
- package/src/views/PostManager/PostTable.js +0 -79
- package/src/views/PostManager/PostTable.tsx +0 -230
- package/src/views/PostManager/index.d.ts +0 -12
- package/src/views/PostManager/index.d.ts.map +0 -1
- package/src/views/PostManager/index.js +0 -11
- package/src/views/PostManager/index.ts +0 -15
- package/src/views/Preview/PreviewBridgeView.d.ts +0 -12
- package/src/views/Preview/PreviewBridgeView.d.ts.map +0 -1
- package/src/views/Preview/PreviewBridgeView.js +0 -11
- package/src/views/Preview/PreviewBridgeView.tsx +0 -64
- package/src/views/Preview/index.d.ts +0 -6
- package/src/views/Preview/index.d.ts.map +0 -1
- package/src/views/Preview/index.js +0 -4
- package/src/views/Preview/index.ts +0 -7
- package/src/views/Settings/SettingsView.d.ts +0 -10
- package/src/views/Settings/SettingsView.d.ts.map +0 -1
- package/src/views/Settings/SettingsView.js +0 -111
- package/src/views/Settings/SettingsView.tsx +0 -298
- package/src/views/Settings/index.d.ts +0 -6
- package/src/views/Settings/index.d.ts.map +0 -1
- package/src/views/Settings/index.js +0 -4
- package/src/views/Settings/index.ts +0 -7
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts +0 -12
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +0 -1
- package/src/views/SlugSEO/SlugSEOManagerView.js +0 -11
- package/src/views/SlugSEO/SlugSEOManagerView.tsx +0 -94
- package/src/views/SlugSEO/index.d.ts +0 -6
- package/src/views/SlugSEO/index.d.ts.map +0 -1
- package/src/views/SlugSEO/index.js +0 -4
- package/src/views/SlugSEO/index.ts +0 -7
package/src/hooks/useBlogs.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useBlogs Hook
|
|
3
|
-
* React hook for fetching blog posts in client applications
|
|
4
|
-
*/
|
|
5
|
-
import { useState, useEffect } from 'react';
|
|
6
|
-
import { apiToBlogPost } from '../lib/mappers/apiMapper';
|
|
7
|
-
/**
|
|
8
|
-
* React hook to fetch blog posts
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```tsx
|
|
12
|
-
* const { blogs, loading, error } = useBlogs({ limit: 5 });
|
|
13
|
-
* ```
|
|
14
|
-
*/
|
|
15
|
-
export function useBlogs(options = {}) {
|
|
16
|
-
const { limit = 10, skip = 0, status, admin = false, apiBaseUrl = '/api/plugin-blog', } = options;
|
|
17
|
-
const [blogs, setBlogs] = useState([]);
|
|
18
|
-
const [loading, setLoading] = useState(true);
|
|
19
|
-
const [error, setError] = useState(null);
|
|
20
|
-
const [total, setTotal] = useState(0);
|
|
21
|
-
const fetchBlogs = async () => {
|
|
22
|
-
try {
|
|
23
|
-
setLoading(true);
|
|
24
|
-
setError(null);
|
|
25
|
-
const params = new URLSearchParams();
|
|
26
|
-
if (limit)
|
|
27
|
-
params.set('limit', limit.toString());
|
|
28
|
-
if (skip)
|
|
29
|
-
params.set('skip', skip.toString());
|
|
30
|
-
if (status)
|
|
31
|
-
params.set('status', status);
|
|
32
|
-
if (admin)
|
|
33
|
-
params.set('admin', 'true');
|
|
34
|
-
const url = `${apiBaseUrl}?${params.toString()}`;
|
|
35
|
-
const response = await fetch(url);
|
|
36
|
-
if (!response.ok) {
|
|
37
|
-
throw new Error(`Failed to fetch blogs: ${response.status}`);
|
|
38
|
-
}
|
|
39
|
-
const data = await response.json();
|
|
40
|
-
// Handle error response
|
|
41
|
-
if (data.error) {
|
|
42
|
-
throw new Error(data.error || 'Failed to fetch blogs');
|
|
43
|
-
}
|
|
44
|
-
// Convert API format to PostListItem format
|
|
45
|
-
const blogsArray = Array.isArray(data.blogs) ? data.blogs : [];
|
|
46
|
-
const convertedBlogs = blogsArray.map((apiDoc) => {
|
|
47
|
-
const blogPost = apiToBlogPost(apiDoc);
|
|
48
|
-
return {
|
|
49
|
-
id: blogPost.id,
|
|
50
|
-
title: blogPost.title,
|
|
51
|
-
slug: blogPost.slug,
|
|
52
|
-
excerpt: blogPost.metadata.excerpt || '',
|
|
53
|
-
status: blogPost.publication.status,
|
|
54
|
-
authorId: blogPost.publication.authorId || '',
|
|
55
|
-
updatedAt: blogPost.updatedAt,
|
|
56
|
-
featuredImage: blogPost.metadata.featuredImage,
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
setBlogs(convertedBlogs);
|
|
60
|
-
setTotal(data.total || convertedBlogs.length);
|
|
61
|
-
}
|
|
62
|
-
catch (err) {
|
|
63
|
-
console.error('[useBlogs] Error fetching blogs:', err);
|
|
64
|
-
setError(err.message || 'Failed to fetch blogs');
|
|
65
|
-
setBlogs([]);
|
|
66
|
-
setTotal(0);
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
setLoading(false);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
useEffect(() => {
|
|
73
|
-
fetchBlogs();
|
|
74
|
-
}, [limit, skip, status, admin, apiBaseUrl]);
|
|
75
|
-
return {
|
|
76
|
-
blogs,
|
|
77
|
-
loading,
|
|
78
|
-
error,
|
|
79
|
-
total,
|
|
80
|
-
refetch: fetchBlogs,
|
|
81
|
-
};
|
|
82
|
-
}
|
package/src/hooks/useBlogs.ts
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useBlogs Hook
|
|
3
|
-
* React hook for fetching blog posts in client applications
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { useState, useEffect } from 'react';
|
|
7
|
-
import { apiToBlogPost, type APIBlogDocument } from '../lib/mappers/apiMapper';
|
|
8
|
-
import { PostListItem } from '../types/post';
|
|
9
|
-
|
|
10
|
-
export interface UseBlogsOptions {
|
|
11
|
-
/** Maximum number of posts to fetch (default: 10) */
|
|
12
|
-
limit?: number;
|
|
13
|
-
/** Number of posts to skip (default: 0) */
|
|
14
|
-
skip?: number;
|
|
15
|
-
/** Filter by status (published, draft, concept) */
|
|
16
|
-
status?: string;
|
|
17
|
-
/** Whether to fetch all posts for admin (includes drafts) */
|
|
18
|
-
admin?: boolean;
|
|
19
|
-
/** API base URL (default: '/api/blogs') */
|
|
20
|
-
apiBaseUrl?: string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export interface UseBlogsResult {
|
|
24
|
-
/** Array of blog posts */
|
|
25
|
-
blogs: PostListItem[];
|
|
26
|
-
/** Whether data is currently loading */
|
|
27
|
-
loading: boolean;
|
|
28
|
-
/** Error message if fetch failed */
|
|
29
|
-
error: string | null;
|
|
30
|
-
/** Total number of posts available */
|
|
31
|
-
total: number;
|
|
32
|
-
/** Function to refetch blogs */
|
|
33
|
-
refetch: () => Promise<void>;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* React hook to fetch blog posts
|
|
38
|
-
*
|
|
39
|
-
* @example
|
|
40
|
-
* ```tsx
|
|
41
|
-
* const { blogs, loading, error } = useBlogs({ limit: 5 });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export function useBlogs(options: UseBlogsOptions = {}): UseBlogsResult {
|
|
45
|
-
const {
|
|
46
|
-
limit = 10,
|
|
47
|
-
skip = 0,
|
|
48
|
-
status,
|
|
49
|
-
admin = false,
|
|
50
|
-
apiBaseUrl = '/api/plugin-blog',
|
|
51
|
-
} = options;
|
|
52
|
-
|
|
53
|
-
const [blogs, setBlogs] = useState<PostListItem[]>([]);
|
|
54
|
-
const [loading, setLoading] = useState(true);
|
|
55
|
-
const [error, setError] = useState<string | null>(null);
|
|
56
|
-
const [total, setTotal] = useState(0);
|
|
57
|
-
|
|
58
|
-
const fetchBlogs = async () => {
|
|
59
|
-
try {
|
|
60
|
-
setLoading(true);
|
|
61
|
-
setError(null);
|
|
62
|
-
|
|
63
|
-
const params = new URLSearchParams();
|
|
64
|
-
if (limit) params.set('limit', limit.toString());
|
|
65
|
-
if (skip) params.set('skip', skip.toString());
|
|
66
|
-
if (status) params.set('status', status);
|
|
67
|
-
if (admin) params.set('admin', 'true');
|
|
68
|
-
|
|
69
|
-
const url = `${apiBaseUrl}?${params.toString()}`;
|
|
70
|
-
const response = await fetch(url);
|
|
71
|
-
|
|
72
|
-
if (!response.ok) {
|
|
73
|
-
throw new Error(`Failed to fetch blogs: ${response.status}`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const data = await response.json();
|
|
77
|
-
|
|
78
|
-
// Handle error response
|
|
79
|
-
if (data.error) {
|
|
80
|
-
throw new Error(data.error || 'Failed to fetch blogs');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Convert API format to PostListItem format
|
|
84
|
-
const blogsArray = Array.isArray(data.blogs) ? data.blogs : [];
|
|
85
|
-
const convertedBlogs: PostListItem[] = blogsArray.map((apiDoc: APIBlogDocument) => {
|
|
86
|
-
const blogPost = apiToBlogPost(apiDoc);
|
|
87
|
-
return {
|
|
88
|
-
id: blogPost.id,
|
|
89
|
-
title: blogPost.title,
|
|
90
|
-
slug: blogPost.slug,
|
|
91
|
-
excerpt: blogPost.metadata.excerpt || '',
|
|
92
|
-
status: blogPost.publication.status,
|
|
93
|
-
authorId: blogPost.publication.authorId || '',
|
|
94
|
-
updatedAt: blogPost.updatedAt,
|
|
95
|
-
featuredImage: blogPost.metadata.featuredImage,
|
|
96
|
-
};
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
setBlogs(convertedBlogs);
|
|
100
|
-
setTotal(data.total || convertedBlogs.length);
|
|
101
|
-
} catch (err: any) {
|
|
102
|
-
console.error('[useBlogs] Error fetching blogs:', err);
|
|
103
|
-
setError(err.message || 'Failed to fetch blogs');
|
|
104
|
-
setBlogs([]);
|
|
105
|
-
setTotal(0);
|
|
106
|
-
} finally {
|
|
107
|
-
setLoading(false);
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
fetchBlogs();
|
|
113
|
-
}, [limit, skip, status, admin, apiBaseUrl]);
|
|
114
|
-
|
|
115
|
-
return {
|
|
116
|
-
blogs,
|
|
117
|
-
loading,
|
|
118
|
-
error,
|
|
119
|
-
total,
|
|
120
|
-
refetch: fetchBlogs,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["useCategories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,wBAAgB,aAAa;;;EAkE5B"}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook to fetch categories from existing blog posts
|
|
3
|
-
* Extracts categories from Hero blocks in all posts
|
|
4
|
-
*/
|
|
5
|
-
'use client';
|
|
6
|
-
import { useState, useEffect } from 'react';
|
|
7
|
-
export function useCategories() {
|
|
8
|
-
const [categories, setCategories] = useState([]);
|
|
9
|
-
const [loading, setLoading] = useState(true);
|
|
10
|
-
useEffect(() => {
|
|
11
|
-
const fetchCategories = async () => {
|
|
12
|
-
try {
|
|
13
|
-
const categorySet = new Set();
|
|
14
|
-
// 1. Fetch from categories endpoint (legacy categoryTags.category)
|
|
15
|
-
try {
|
|
16
|
-
const categoriesResponse = await fetch('/api/plugin-blog/categories');
|
|
17
|
-
if (categoriesResponse.ok) {
|
|
18
|
-
const categoriesData = await categoriesResponse.json();
|
|
19
|
-
if (Array.isArray(categoriesData.categories)) {
|
|
20
|
-
categoriesData.categories.forEach((cat) => {
|
|
21
|
-
if (cat && cat.trim()) {
|
|
22
|
-
categorySet.add(cat.trim());
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
catch (e) {
|
|
29
|
-
// Categories endpoint not available, continue
|
|
30
|
-
}
|
|
31
|
-
// 2. Fetch all blog posts and extract categories from Hero blocks
|
|
32
|
-
try {
|
|
33
|
-
const response = await fetch('/api/plugin-blog?admin=true&limit=1000');
|
|
34
|
-
if (response.ok) {
|
|
35
|
-
const data = await response.json();
|
|
36
|
-
const posts = Array.isArray(data.blogs) ? data.blogs : (Array.isArray(data) ? data : []);
|
|
37
|
-
posts.forEach((post) => {
|
|
38
|
-
if (post.blocks && Array.isArray(post.blocks)) {
|
|
39
|
-
// Find Hero block
|
|
40
|
-
const heroBlock = post.blocks.find((block) => block.type === 'hero');
|
|
41
|
-
if (heroBlock && heroBlock.data && heroBlock.data.category) {
|
|
42
|
-
const category = heroBlock.data.category.trim();
|
|
43
|
-
if (category) {
|
|
44
|
-
categorySet.add(category);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
console.error('Failed to fetch posts for categories:', e);
|
|
53
|
-
}
|
|
54
|
-
// Convert to sorted array
|
|
55
|
-
const sortedCategories = Array.from(categorySet).sort();
|
|
56
|
-
setCategories(sortedCategories);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error('Failed to fetch categories:', error);
|
|
60
|
-
// Fallback to empty array
|
|
61
|
-
setCategories([]);
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
setLoading(false);
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
fetchCategories();
|
|
68
|
-
}, []);
|
|
69
|
-
return { categories, loading };
|
|
70
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook to fetch categories from existing blog posts
|
|
3
|
-
* Extracts categories from Hero blocks in all posts
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
'use client';
|
|
7
|
-
|
|
8
|
-
import { useState, useEffect } from 'react';
|
|
9
|
-
|
|
10
|
-
export function useCategories() {
|
|
11
|
-
const [categories, setCategories] = useState<string[]>([]);
|
|
12
|
-
const [loading, setLoading] = useState(true);
|
|
13
|
-
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
const fetchCategories = async () => {
|
|
16
|
-
try {
|
|
17
|
-
const categorySet = new Set<string>();
|
|
18
|
-
|
|
19
|
-
// 1. Fetch from categories endpoint (legacy categoryTags.category)
|
|
20
|
-
try {
|
|
21
|
-
const categoriesResponse = await fetch('/api/plugin-blog/categories');
|
|
22
|
-
if (categoriesResponse.ok) {
|
|
23
|
-
const categoriesData = await categoriesResponse.json();
|
|
24
|
-
if (Array.isArray(categoriesData.categories)) {
|
|
25
|
-
categoriesData.categories.forEach((cat: string) => {
|
|
26
|
-
if (cat && cat.trim()) {
|
|
27
|
-
categorySet.add(cat.trim());
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
} catch (e) {
|
|
33
|
-
// Categories endpoint not available, continue
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// 2. Fetch all blog posts and extract categories from Hero blocks
|
|
37
|
-
try {
|
|
38
|
-
const response = await fetch('/api/plugin-blog?admin=true&limit=1000');
|
|
39
|
-
if (response.ok) {
|
|
40
|
-
const data = await response.json();
|
|
41
|
-
const posts = Array.isArray(data.blogs) ? data.blogs : (Array.isArray(data) ? data : []);
|
|
42
|
-
|
|
43
|
-
posts.forEach((post: any) => {
|
|
44
|
-
if (post.blocks && Array.isArray(post.blocks)) {
|
|
45
|
-
// Find Hero block
|
|
46
|
-
const heroBlock = post.blocks.find((block: any) => block.type === 'hero');
|
|
47
|
-
if (heroBlock && heroBlock.data && heroBlock.data.category) {
|
|
48
|
-
const category = heroBlock.data.category.trim();
|
|
49
|
-
if (category) {
|
|
50
|
-
categorySet.add(category);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
} catch (e) {
|
|
57
|
-
console.error('Failed to fetch posts for categories:', e);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Convert to sorted array
|
|
61
|
-
const sortedCategories = Array.from(categorySet).sort();
|
|
62
|
-
setCategories(sortedCategories);
|
|
63
|
-
} catch (error) {
|
|
64
|
-
console.error('Failed to fetch categories:', error);
|
|
65
|
-
// Fallback to empty array
|
|
66
|
-
setCategories([]);
|
|
67
|
-
} finally {
|
|
68
|
-
setLoading(false);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
fetchCategories();
|
|
73
|
-
}, []);
|
|
74
|
-
|
|
75
|
-
return { categories, loading };
|
|
76
|
-
}
|
package/src/index.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin Blog - Main Entry Point
|
|
3
|
-
* Block-Based Blog Management System
|
|
4
|
-
* Multi-Tenant Architecture: Accepts custom blocks from client applications
|
|
5
|
-
*/
|
|
6
|
-
import { ClientBlockDefinition } from './types/block';
|
|
7
|
-
/**
|
|
8
|
-
* Plugin Props Interface
|
|
9
|
-
* Matches the PluginProps from @jhits/jhits-dashboard
|
|
10
|
-
*/
|
|
11
|
-
export interface PluginProps {
|
|
12
|
-
subPath: string[];
|
|
13
|
-
siteId: string;
|
|
14
|
-
locale: string;
|
|
15
|
-
/** Custom blocks from client application (optional, can also come from window.__JHITS_PLUGIN_PROPS__) */
|
|
16
|
-
customBlocks?: ClientBlockDefinition[];
|
|
17
|
-
/** Enable dark mode for content area and wrappers (default: true) */
|
|
18
|
-
darkMode?: boolean;
|
|
19
|
-
/** Background colors for the editor */
|
|
20
|
-
backgroundColors?: {
|
|
21
|
-
/** Background color for light mode (REQUIRED) */
|
|
22
|
-
light: string;
|
|
23
|
-
/** Background color for dark mode (optional) */
|
|
24
|
-
dark?: string;
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Main Router Component
|
|
29
|
-
* Handles routing within the blog plugin
|
|
30
|
-
*
|
|
31
|
-
* Client Handshake:
|
|
32
|
-
* - Client apps can pass customBlocks via props
|
|
33
|
-
* - Or via window.__JHITS_PLUGIN_PROPS__['plugin-blog'].customBlocks
|
|
34
|
-
* - The EditorProvider will automatically register these blocks
|
|
35
|
-
*/
|
|
36
|
-
export default function BlogPlugin(props: PluginProps): import("react/jsx-runtime").JSX.Element;
|
|
37
|
-
export { BlogPlugin as Index };
|
|
38
|
-
export type { Block, BlockTypeDefinition, ClientBlockDefinition, RichTextFormattingConfig, BlockEditProps, BlockPreviewProps, IBlockComponent, } from './types';
|
|
39
|
-
export type { SEOMetadata, PublicationData, PostStatus, PostMetadata, BlogPost, PostListItem, PostFilterOptions, } from './types/post';
|
|
40
|
-
export { initBlogPlugin } from './init';
|
|
41
|
-
export type { BlogPluginConfig } from './init';
|
|
42
|
-
export { RichTextEditor, RichTextPreview } from './lib/rich-text';
|
|
43
|
-
export type { RichTextEditorProps, RichTextPreviewProps } from './lib/rich-text';
|
|
44
|
-
export { useBlogs, useBlog } from './hooks';
|
|
45
|
-
export type { UseBlogsOptions, UseBlogsResult, UseBlogOptions, UseBlogResult } from './hooks';
|
|
46
|
-
export { fetchBlogs, fetchBlog } from './utils/client';
|
|
47
|
-
export type { FetchBlogsOptions, FetchBlogsResult, FetchBlogOptions } from './utils/client';
|
|
48
|
-
export { BlockRenderer, BlocksRenderer } from './lib/blocks/BlockRenderer';
|
|
49
|
-
export { blockRegistry } from './registry';
|
|
50
|
-
export { registerLayoutBlocks } from './lib/layouts/registerLayoutBlocks';
|
|
51
|
-
export { getPluginConfig, savePluginConfig } from './lib/config-storage';
|
|
52
|
-
export { EditorProvider, useEditor } from './state/EditorContext';
|
|
53
|
-
export type { EditorProviderProps, EditorState, EditorContextValue } from './state';
|
|
54
|
-
export { useCategories } from './hooks/useCategories';
|
|
55
|
-
//# sourceMappingURL=index.d.ts.map
|
package/src/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAStD;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,yGAAyG;IACzG,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,gDAAgD;QAChD,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACL;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,KAAK,EAAE,WAAW,2CA4NpD;AAID,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,CAAC;AAG/B,YAAY,EACR,KAAK,EACL,mBAAmB,EACnB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,iBAAiB,EACjB,eAAe,GAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACR,WAAW,EACX,eAAe,EACf,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,iBAAiB,GACpB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,YAAY,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAG/C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAGjF,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAG9F,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG5F,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAG3E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1E,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGzE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGpF,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
package/src/index.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Plugin Blog - Main Entry Point
|
|
3
|
-
* Block-Based Blog Management System
|
|
4
|
-
* Multi-Tenant Architecture: Accepts custom blocks from client applications
|
|
5
|
-
*/
|
|
6
|
-
'use client';
|
|
7
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
|
-
import { useMemo, useEffect } from 'react';
|
|
9
|
-
import { EditorProvider } from './state/EditorContext';
|
|
10
|
-
import { PostManagerView } from './views/PostManager';
|
|
11
|
-
import { CanvasEditorView } from './views/CanvasEditor';
|
|
12
|
-
import { editorStateToAPI } from './lib/mappers/apiMapper';
|
|
13
|
-
import { SlugSEOManagerView } from './views/SlugSEO';
|
|
14
|
-
import { PreviewBridgeView } from './views/Preview';
|
|
15
|
-
import { SettingsView } from './views/Settings';
|
|
16
|
-
import { useHeroBlockValidation, findHeroBlock } from './lib/utils/configValidation';
|
|
17
|
-
/**
|
|
18
|
-
* Main Router Component
|
|
19
|
-
* Handles routing within the blog plugin
|
|
20
|
-
*
|
|
21
|
-
* Client Handshake:
|
|
22
|
-
* - Client apps can pass customBlocks via props
|
|
23
|
-
* - Or via window.__JHITS_PLUGIN_PROPS__['plugin-blog'].customBlocks
|
|
24
|
-
* - The EditorProvider will automatically register these blocks
|
|
25
|
-
*/
|
|
26
|
-
export default function BlogPlugin(props) {
|
|
27
|
-
const { subPath, siteId, locale, customBlocks: propsCustomBlocks, darkMode: propsDarkMode, backgroundColors: propsBackgroundColors } = props;
|
|
28
|
-
// Get custom blocks from props or window global (client app injection point)
|
|
29
|
-
const customBlocks = useMemo(() => {
|
|
30
|
-
// First, try props
|
|
31
|
-
if (propsCustomBlocks && propsCustomBlocks.length > 0) {
|
|
32
|
-
return propsCustomBlocks;
|
|
33
|
-
}
|
|
34
|
-
// Fallback to window global (for client app injection)
|
|
35
|
-
if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
|
|
36
|
-
const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-blog'];
|
|
37
|
-
if (pluginProps === null || pluginProps === void 0 ? void 0 : pluginProps.customBlocks) {
|
|
38
|
-
return pluginProps.customBlocks;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return [];
|
|
42
|
-
}, [propsCustomBlocks]);
|
|
43
|
-
// Get dark mode setting from props, localStorage (dev settings), or window global
|
|
44
|
-
// Priority: localStorage (dev) > props > window global > default
|
|
45
|
-
const darkMode = useMemo(() => {
|
|
46
|
-
// First, check localStorage for dev settings (highest priority for dev)
|
|
47
|
-
if (typeof window !== 'undefined') {
|
|
48
|
-
try {
|
|
49
|
-
const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
|
|
50
|
-
if (saved) {
|
|
51
|
-
const config = JSON.parse(saved);
|
|
52
|
-
if (config.darkMode !== undefined) {
|
|
53
|
-
return config.darkMode;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
// Ignore localStorage errors
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Then try props
|
|
62
|
-
if (propsDarkMode !== undefined) {
|
|
63
|
-
return propsDarkMode;
|
|
64
|
-
}
|
|
65
|
-
// Fallback to window global if prop not provided
|
|
66
|
-
if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
|
|
67
|
-
const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-blog'];
|
|
68
|
-
if ((pluginProps === null || pluginProps === void 0 ? void 0 : pluginProps.darkMode) !== undefined) {
|
|
69
|
-
return pluginProps.darkMode;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return true; // Default to dark mode enabled
|
|
73
|
-
}, [propsDarkMode]);
|
|
74
|
-
// Get background colors from props, localStorage (dev settings), or window global
|
|
75
|
-
// Priority: localStorage (dev) > props > window global
|
|
76
|
-
const backgroundColors = useMemo(() => {
|
|
77
|
-
// First, check localStorage for dev settings (highest priority for dev)
|
|
78
|
-
if (typeof window !== 'undefined') {
|
|
79
|
-
try {
|
|
80
|
-
const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
|
|
81
|
-
if (saved) {
|
|
82
|
-
const config = JSON.parse(saved);
|
|
83
|
-
if (config.backgroundColors) {
|
|
84
|
-
return config.backgroundColors;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
// Ignore localStorage errors
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
// Then try props
|
|
93
|
-
if (propsBackgroundColors) {
|
|
94
|
-
return propsBackgroundColors;
|
|
95
|
-
}
|
|
96
|
-
// Fallback to window global
|
|
97
|
-
if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
|
|
98
|
-
const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-blog'];
|
|
99
|
-
if (pluginProps === null || pluginProps === void 0 ? void 0 : pluginProps.backgroundColors) {
|
|
100
|
-
return pluginProps.backgroundColors;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
return undefined;
|
|
104
|
-
}, [propsBackgroundColors]);
|
|
105
|
-
const route = subPath[0] || 'posts';
|
|
106
|
-
// Validate hero block configuration (only checks when needed)
|
|
107
|
-
useHeroBlockValidation(route, customBlocks, propsCustomBlocks);
|
|
108
|
-
// Get hero block definition for logging/debugging (only for routes that need it)
|
|
109
|
-
const heroBlockDefinition = useMemo(() => {
|
|
110
|
-
const needsHeroBlock = route === 'editor' || route === 'new' || route === 'preview';
|
|
111
|
-
return needsHeroBlock ? findHeroBlock(customBlocks) : undefined;
|
|
112
|
-
}, [customBlocks, route]);
|
|
113
|
-
// Listen for config updates from settings screen
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
if (typeof window === 'undefined')
|
|
116
|
-
return;
|
|
117
|
-
const handleConfigUpdate = () => {
|
|
118
|
-
// Reload page to apply changes (simplest way to ensure all components pick up new values)
|
|
119
|
-
window.location.reload();
|
|
120
|
-
};
|
|
121
|
-
window.addEventListener('blog-plugin-config-updated', handleConfigUpdate);
|
|
122
|
-
return () => {
|
|
123
|
-
window.removeEventListener('blog-plugin-config-updated', handleConfigUpdate);
|
|
124
|
-
};
|
|
125
|
-
}, []);
|
|
126
|
-
if (heroBlockDefinition !== undefined) {
|
|
127
|
-
console.log('[BlogPlugin] Hero block definition:', heroBlockDefinition ? 'found' : 'not found (REQUIRED)');
|
|
128
|
-
}
|
|
129
|
-
// Route to appropriate view
|
|
130
|
-
switch (route) {
|
|
131
|
-
case 'posts':
|
|
132
|
-
return _jsx(PostManagerView, { siteId: siteId, locale: locale });
|
|
133
|
-
case 'editor':
|
|
134
|
-
const postId = subPath[1]; // This is actually the slug, not the ID
|
|
135
|
-
return (_jsx(EditorProvider, { customBlocks: customBlocks, darkMode: darkMode, backgroundColors: backgroundColors, onSave: async (state, heroBlock) => {
|
|
136
|
-
// Save to API - update existing post
|
|
137
|
-
// Use the route postId (original slug) to identify which blog to update
|
|
138
|
-
// If route postId is missing, use state.slug or state.postId as fallback
|
|
139
|
-
const originalSlug = postId || state.slug || state.postId;
|
|
140
|
-
if (!originalSlug) {
|
|
141
|
-
throw new Error('Cannot save: no post identifier available. Please reload the page.');
|
|
142
|
-
}
|
|
143
|
-
console.log('[BlogPlugin] Saving post with slug:', originalSlug);
|
|
144
|
-
const apiData = editorStateToAPI(state, undefined, heroBlock);
|
|
145
|
-
const response = await fetch(`/api/plugin-blog/${originalSlug}`, {
|
|
146
|
-
method: 'PUT',
|
|
147
|
-
headers: { 'Content-Type': 'application/json' },
|
|
148
|
-
credentials: 'include', // Include cookies for authentication
|
|
149
|
-
body: JSON.stringify(apiData),
|
|
150
|
-
});
|
|
151
|
-
if (!response.ok) {
|
|
152
|
-
const error = await response.json();
|
|
153
|
-
console.error('[BlogPlugin] Save failed:', {
|
|
154
|
-
status: response.status,
|
|
155
|
-
statusText: response.statusText,
|
|
156
|
-
error,
|
|
157
|
-
missingFields: error.missingFields,
|
|
158
|
-
});
|
|
159
|
-
// Provide more detailed error message if available
|
|
160
|
-
const errorMessage = error.message || error.error || 'Failed to save post';
|
|
161
|
-
const missingFieldsMsg = error.missingFields && error.missingFields.length > 0
|
|
162
|
-
? ` Missing: ${error.missingFields.join(', ')}`
|
|
163
|
-
: '';
|
|
164
|
-
throw new Error(errorMessage + missingFieldsMsg);
|
|
165
|
-
}
|
|
166
|
-
const result = await response.json();
|
|
167
|
-
// If the slug changed, update the URL
|
|
168
|
-
if (result.slug && result.slug !== originalSlug) {
|
|
169
|
-
window.history.replaceState(null, '', `/dashboard/blog/editor/${result.slug}`);
|
|
170
|
-
}
|
|
171
|
-
return result;
|
|
172
|
-
}, children: _jsx(CanvasEditorView, { postId: postId, siteId: siteId, locale: locale, darkMode: darkMode, backgroundColors: backgroundColors }) }));
|
|
173
|
-
case 'new':
|
|
174
|
-
return (_jsx(EditorProvider, { customBlocks: customBlocks, darkMode: darkMode, backgroundColors: backgroundColors, onSave: async (state) => {
|
|
175
|
-
// Save to API - create new post
|
|
176
|
-
const apiData = editorStateToAPI(state);
|
|
177
|
-
const response = await fetch('/api/plugin-blog/new', {
|
|
178
|
-
method: 'POST',
|
|
179
|
-
headers: { 'Content-Type': 'application/json' },
|
|
180
|
-
credentials: 'include', // Include cookies for authentication
|
|
181
|
-
body: JSON.stringify(apiData),
|
|
182
|
-
});
|
|
183
|
-
if (!response.ok) {
|
|
184
|
-
const error = await response.json();
|
|
185
|
-
throw new Error(error.message || 'Failed to create post');
|
|
186
|
-
}
|
|
187
|
-
const result = await response.json();
|
|
188
|
-
// Update the URL to the new post's slug
|
|
189
|
-
if (result.slug) {
|
|
190
|
-
window.history.replaceState(null, '', `/dashboard/blog/editor/${result.slug}`);
|
|
191
|
-
}
|
|
192
|
-
return result;
|
|
193
|
-
}, children: _jsx(CanvasEditorView, { siteId: siteId, locale: locale, darkMode: darkMode, backgroundColors: backgroundColors }) }));
|
|
194
|
-
case 'seo':
|
|
195
|
-
const seoPostId = subPath[1];
|
|
196
|
-
return _jsx(SlugSEOManagerView, { postId: seoPostId, siteId: siteId, locale: locale });
|
|
197
|
-
case 'preview':
|
|
198
|
-
const previewPostId = subPath[1];
|
|
199
|
-
return _jsx(PreviewBridgeView, { postId: previewPostId, siteId: siteId, locale: locale });
|
|
200
|
-
case 'settings':
|
|
201
|
-
case 'install':
|
|
202
|
-
return _jsx(SettingsView, { siteId: siteId, locale: locale });
|
|
203
|
-
default:
|
|
204
|
-
return _jsx(PostManagerView, { siteId: siteId, locale: locale });
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
// Export for use as default
|
|
208
|
-
export { BlogPlugin as Index };
|
|
209
|
-
// Export initialization utility for easy setup
|
|
210
|
-
export { initBlogPlugin } from './init';
|
|
211
|
-
// Export rich text components for client applications
|
|
212
|
-
export { RichTextEditor, RichTextPreview } from './lib/rich-text';
|
|
213
|
-
// Export hooks for client applications
|
|
214
|
-
export { useBlogs, useBlog } from './hooks';
|
|
215
|
-
// Export client utilities
|
|
216
|
-
export { fetchBlogs, fetchBlog } from './utils/client';
|
|
217
|
-
// Export block rendering components
|
|
218
|
-
export { BlockRenderer, BlocksRenderer } from './lib/blocks/BlockRenderer';
|
|
219
|
-
// Export block registry
|
|
220
|
-
export { blockRegistry } from './registry';
|
|
221
|
-
// Export layout block registration
|
|
222
|
-
export { registerLayoutBlocks } from './lib/layouts/registerLayoutBlocks';
|
|
223
|
-
// Export config storage utilities
|
|
224
|
-
export { getPluginConfig, savePluginConfig } from './lib/config-storage';
|
|
225
|
-
// Export editor state management
|
|
226
|
-
export { EditorProvider, useEditor } from './state/EditorContext';
|
|
227
|
-
// Export hooks
|
|
228
|
-
export { useCategories } from './hooks/useCategories';
|
package/src/index.server.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import 'server-only';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Plugin Blog - Server-Only Entry Point
|
|
5
|
-
* This file exports only server-side API handlers
|
|
6
|
-
* Used by the dynamic plugin router via @jhits/plugin-blog/server
|
|
7
|
-
*
|
|
8
|
-
* Note: This file is server-only (no 'use server' needed - that's only for Server Actions)
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
export { handleBlogApi as handleApi } from './api/router';
|
|
12
|
-
export { handleBlogApi } from './api/router'; // Keep original export for backward compatibility
|
|
13
|
-
export type { BlogApiRouterConfig } from './api/router';
|
|
14
|
-
|