@jhits/plugin-blog 0.0.18 → 0.0.20
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.map +1 -1
- package/dist/api/categories.js +42 -38
- package/dist/api/handler.d.ts +1 -26
- package/dist/api/handler.d.ts.map +1 -1
- package/dist/api/handler.js +81 -500
- package/dist/api/router.d.ts +0 -5
- package/dist/api/router.d.ts.map +1 -1
- package/dist/api/router.js +8 -35
- package/dist/api/service.d.ts +80 -0
- package/dist/api/service.d.ts.map +1 -0
- package/dist/api/service.js +219 -0
- package/dist/hooks/useAutoSave.d.ts +10 -0
- package/dist/hooks/useAutoSave.d.ts.map +1 -0
- package/dist/hooks/useAutoSave.js +57 -0
- package/dist/hooks/useCategories.d.ts +1 -1
- package/dist/hooks/useCategories.d.ts.map +1 -1
- package/dist/hooks/useCategories.js +15 -46
- package/dist/index.d.ts +24 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -201
- package/dist/init.d.ts +20 -7
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +8 -7
- package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -1
- package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -1
- package/dist/lib/layouts/blocks/ColumnsBlock.js +30 -113
- package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -1
- package/dist/lib/layouts/blocks/SectionBlock.js +9 -21
- package/dist/lib/layouts/index.d.ts +3 -3
- package/dist/lib/layouts/index.js +4 -4
- package/dist/lib/mappers/apiMapper.d.ts +10 -0
- package/dist/lib/mappers/apiMapper.d.ts.map +1 -1
- package/dist/lib/mappers/apiMapper.js +47 -32
- package/dist/lib/rich-text/RichTextEditor.d.ts +4 -2
- package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -1
- package/dist/lib/rich-text/RichTextEditor.js +12 -9
- package/dist/lib/utils/config-resolver.d.ts +28 -0
- package/dist/lib/utils/config-resolver.d.ts.map +1 -0
- package/dist/lib/utils/config-resolver.js +46 -0
- package/dist/lib/utils/tree.d.ts +29 -0
- package/dist/lib/utils/tree.d.ts.map +1 -0
- package/dist/lib/utils/tree.js +129 -0
- package/dist/state/EditorContext.d.ts +3 -25
- package/dist/state/EditorContext.d.ts.map +1 -1
- package/dist/state/EditorContext.js +124 -174
- package/dist/state/reducer.d.ts +1 -5
- package/dist/state/reducer.d.ts.map +1 -1
- package/dist/state/reducer.js +128 -521
- package/dist/state/types.d.ts +12 -1
- package/dist/state/types.d.ts.map +1 -1
- package/dist/types/block.d.ts +9 -0
- package/dist/types/block.d.ts.map +1 -1
- package/dist/types/post.d.ts +17 -1
- package/dist/types/post.d.ts.map +1 -1
- package/dist/views/CanvasEditor/BlockWrapper.d.ts +5 -6
- package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -1
- package/dist/views/CanvasEditor/BlockWrapper.js +56 -264
- package/dist/views/CanvasEditor/CanvasEditorView.d.ts +5 -3
- package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
- package/dist/views/CanvasEditor/CanvasEditorView.js +55 -315
- package/dist/views/CanvasEditor/EditorBody.d.ts +6 -8
- package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -1
- package/dist/views/CanvasEditor/EditorBody.js +34 -482
- package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -1
- package/dist/views/CanvasEditor/EditorHeader.js +27 -63
- package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -1
- package/dist/views/CanvasEditor/LayoutContainer.js +49 -70
- package/dist/views/CanvasEditor/components/CustomBlockItem.js +1 -1
- package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +15 -3
- package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/EditorCanvas.js +40 -18
- package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +5 -1
- package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/EditorLibrary.js +11 -7
- package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/EditorSidebar.js +32 -14
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -6
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +17 -128
- package/dist/views/CanvasEditor/components/JSONInspector.d.ts +9 -0
- package/dist/views/CanvasEditor/components/JSONInspector.d.ts.map +1 -0
- package/dist/views/CanvasEditor/components/JSONInspector.js +56 -0
- package/dist/views/CanvasEditor/components/LibraryItem.js +2 -2
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -4
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +6 -28
- package/dist/views/CanvasEditor/components/index.d.ts +2 -0
- package/dist/views/CanvasEditor/components/index.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/index.js +1 -0
- package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -1
- package/dist/views/CanvasEditor/hooks/useHeroBlock.js +15 -18
- package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +3 -0
- package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -1
- package/dist/views/CanvasEditor/hooks/usePostLoader.js +12 -13
- package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +0 -4
- package/dist/views/PostManager/EmptyState.d.ts +1 -1
- package/dist/views/PostManager/EmptyState.js +4 -4
- package/dist/views/PostManager/FilterDropdown.d.ts +21 -0
- package/dist/views/PostManager/FilterDropdown.d.ts.map +1 -0
- package/dist/views/PostManager/FilterDropdown.js +28 -0
- package/dist/views/PostManager/LanguageFlags.d.ts.map +1 -1
- package/dist/views/PostManager/LanguageFlags.js +4 -1
- package/dist/views/PostManager/PostCards.d.ts.map +1 -1
- package/dist/views/PostManager/PostCards.js +23 -40
- package/dist/views/PostManager/PostFilters.d.ts.map +1 -1
- package/dist/views/PostManager/PostFilters.js +34 -3
- package/dist/views/PostManager/PostManagerView.d.ts +1 -2
- package/dist/views/PostManager/PostManagerView.d.ts.map +1 -1
- package/dist/views/PostManager/PostManagerView.js +30 -96
- package/dist/views/PostManager/PostStats.d.ts.map +1 -1
- package/dist/views/PostManager/PostStats.js +10 -10
- package/dist/views/PostManager/PostTable.d.ts.map +1 -1
- package/dist/views/PostManager/PostTable.js +23 -40
- package/dist/views/Settings/SettingsView.d.ts +1 -1
- package/dist/views/Settings/SettingsView.d.ts.map +1 -1
- package/dist/views/Settings/SettingsView.js +12 -39
- package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -1
- package/dist/views/SlugSEO/SlugSEOManagerView.js +2 -2
- package/package.json +42 -6
- package/src/api/categories.ts +48 -52
- package/src/api/handler.ts +87 -604
- package/src/api/router.ts +15 -65
- package/src/api/service.ts +241 -0
- package/src/hooks/useAutoSave.ts +64 -0
- package/src/hooks/useCategories.ts +19 -47
- package/src/index.tsx +79 -293
- package/src/init.tsx +24 -11
- package/src/lib/blocks/BlockRenderer.tsx +1 -0
- package/src/lib/layouts/blocks/ColumnsBlock.tsx +60 -173
- package/src/lib/layouts/blocks/SectionBlock.tsx +22 -26
- package/src/lib/layouts/index.ts +4 -4
- package/src/lib/mappers/apiMapper.ts +63 -32
- package/src/lib/rich-text/RichTextEditor.tsx +16 -9
- package/src/lib/utils/config-resolver.ts +64 -0
- package/src/lib/utils/tree.ts +150 -0
- package/src/state/EditorContext.tsx +153 -232
- package/src/state/reducer.ts +141 -606
- package/src/state/types.ts +14 -1
- package/src/types/block.ts +10 -0
- package/src/types/post.ts +19 -1
- package/src/views/CanvasEditor/BlockWrapper.tsx +130 -460
- package/src/views/CanvasEditor/CanvasEditorView.tsx +145 -420
- package/src/views/CanvasEditor/EditorBody.tsx +98 -610
- package/src/views/CanvasEditor/EditorHeader.tsx +176 -196
- package/src/views/CanvasEditor/LayoutContainer.tsx +74 -89
- package/src/views/CanvasEditor/components/CustomBlockItem.tsx +7 -8
- package/src/views/CanvasEditor/components/EditorCanvas.tsx +139 -84
- package/src/views/CanvasEditor/components/EditorLibrary.tsx +25 -10
- package/src/views/CanvasEditor/components/EditorSidebar.tsx +196 -127
- package/src/views/CanvasEditor/components/FeaturedMediaSection.tsx +78 -210
- package/src/views/CanvasEditor/components/JSONInspector.tsx +125 -0
- package/src/views/CanvasEditor/components/LibraryItem.tsx +5 -6
- package/src/views/CanvasEditor/components/PrivacySettingsSection.tsx +73 -124
- package/src/views/CanvasEditor/components/index.ts +2 -1
- package/src/views/CanvasEditor/hooks/useHeroBlock.ts +15 -18
- package/src/views/CanvasEditor/hooks/usePostLoader.ts +21 -13
- package/src/views/CanvasEditor/hooks/useUnsavedChanges.ts +4 -4
- package/src/views/PostManager/EmptyState.tsx +9 -10
- package/src/views/PostManager/FilterDropdown.tsx +95 -0
- package/src/views/PostManager/LanguageFlags.tsx +6 -2
- package/src/views/PostManager/PostCards.tsx +127 -133
- package/src/views/PostManager/PostFilters.tsx +73 -68
- package/src/views/PostManager/PostManagerView.tsx +132 -179
- package/src/views/PostManager/PostStats.tsx +21 -20
- package/src/views/PostManager/PostTable.tsx +137 -165
- package/src/views/Settings/SettingsView.tsx +64 -180
- package/src/views/SlugSEO/SlugSEOManagerView.tsx +59 -44
- package/src/hooks/index.d.ts +0 -8
- package/src/hooks/index.d.ts.map +0 -1
- package/src/hooks/useBlog.d.ts +0 -31
- package/src/hooks/useBlog.d.ts.map +0 -1
- package/src/hooks/useBlogs.d.ts +0 -39
- package/src/hooks/useBlogs.d.ts.map +0 -1
- package/src/hooks/useCategories.d.ts +0 -9
- package/src/hooks/useCategories.d.ts.map +0 -1
- package/src/lib/blocks/BlockRenderer.d.ts +0 -54
- package/src/lib/blocks/BlockRenderer.d.ts.map +0 -1
- package/src/lib/config-storage.d.ts +0 -30
- package/src/lib/config-storage.d.ts.map +0 -1
- 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/SectionBlock.d.ts +0 -25
- package/src/lib/layouts/blocks/SectionBlock.d.ts.map +0 -1
- package/src/lib/layouts/index.d.ts +0 -23
- package/src/lib/layouts/index.d.ts.map +0 -1
- package/src/lib/layouts/registerLayoutBlocks.d.ts +0 -9
- package/src/lib/layouts/registerLayoutBlocks.d.ts.map +0 -1
- package/src/lib/mappers/apiMapper.d.ts +0 -66
- package/src/lib/mappers/apiMapper.d.ts.map +0 -1
- 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/RichTextPreview.d.ts +0 -16
- package/src/lib/rich-text/RichTextPreview.d.ts.map +0 -1
- package/src/lib/rich-text/index.d.ts +0 -9
- package/src/lib/rich-text/index.d.ts.map +0 -1
- package/src/lib/utils/blockHelpers.d.ts +0 -23
- package/src/lib/utils/blockHelpers.d.ts.map +0 -1
- package/src/lib/utils/configValidation.d.ts +0 -23
- package/src/lib/utils/configValidation.d.ts.map +0 -1
- package/src/registry/BlockRegistry.d.ts +0 -62
- package/src/registry/BlockRegistry.d.ts.map +0 -1
- package/src/registry/index.d.ts +0 -6
- package/src/registry/index.d.ts.map +0 -1
- package/src/state/EditorContext.d.ts +0 -45
- package/src/state/EditorContext.d.ts.map +0 -1
- package/src/state/index.d.ts +0 -7
- package/src/state/index.d.ts.map +0 -1
- package/src/state/reducer.d.ts +0 -11
- package/src/state/reducer.d.ts.map +0 -1
- package/src/state/types.d.ts +0 -162
- package/src/state/types.d.ts.map +0 -1
- package/src/types/block.d.ts +0 -221
- package/src/types/block.d.ts.map +0 -1
- package/src/types/index.d.ts +0 -8
- package/src/types/index.d.ts.map +0 -1
- package/src/types/post.d.ts +0 -136
- package/src/types/post.d.ts.map +0 -1
- package/src/utils/client.d.ts +0 -48
- package/src/utils/client.d.ts.map +0 -1
- package/src/views/CanvasEditor/BlockWrapper.d.ts +0 -16
- package/src/views/CanvasEditor/BlockWrapper.d.ts.map +0 -1
- package/src/views/CanvasEditor/CanvasEditorView.d.ts +0 -14
- package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +0 -1
- package/src/views/CanvasEditor/EditorBody.d.ts +0 -22
- package/src/views/CanvasEditor/EditorBody.d.ts.map +0 -1
- package/src/views/CanvasEditor/EditorHeader.d.ts +0 -18
- package/src/views/CanvasEditor/EditorHeader.d.ts.map +0 -1
- package/src/views/CanvasEditor/LayoutContainer.d.ts +0 -17
- package/src/views/CanvasEditor/LayoutContainer.d.ts.map +0 -1
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +0 -13
- package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +0 -1
- 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/EditorCanvas.d.ts +0 -29
- package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +0 -1
- 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/EditorSidebar.d.ts +0 -13
- package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +0 -1
- 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/FeaturedMediaSection.d.ts +0 -25
- package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +0 -1
- 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/PrivacySettingsSection.d.ts +0 -15
- package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +0 -1
- 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/hooks/index.d.ts +0 -10
- package/src/views/CanvasEditor/hooks/index.d.ts.map +0 -1
- 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/useKeyboardShortcuts.d.ts +0 -3
- package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +0 -1
- 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/useRegisteredBlocks.d.ts +0 -2
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +0 -1
- 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/index.d.ts +0 -16
- package/src/views/CanvasEditor/index.d.ts.map +0 -1
- package/src/views/PostManager/EmptyState.d.ts +0 -10
- package/src/views/PostManager/EmptyState.d.ts.map +0 -1
- package/src/views/PostManager/PostActionsMenu.d.ts +0 -12
- package/src/views/PostManager/PostActionsMenu.d.ts.map +0 -1
- package/src/views/PostManager/PostCards.d.ts +0 -15
- package/src/views/PostManager/PostCards.d.ts.map +0 -1
- package/src/views/PostManager/PostFilters.d.ts +0 -16
- package/src/views/PostManager/PostFilters.d.ts.map +0 -1
- package/src/views/PostManager/PostManagerView.d.ts +0 -11
- package/src/views/PostManager/PostManagerView.d.ts.map +0 -1
- package/src/views/PostManager/PostStats.d.ts +0 -11
- package/src/views/PostManager/PostStats.d.ts.map +0 -1
- package/src/views/PostManager/PostTable.d.ts +0 -15
- package/src/views/PostManager/PostTable.d.ts.map +0 -1
- package/src/views/PostManager/index.d.ts +0 -12
- package/src/views/PostManager/index.d.ts.map +0 -1
- package/src/views/Preview/PreviewBridgeView.d.ts +0 -12
- package/src/views/Preview/PreviewBridgeView.d.ts.map +0 -1
- package/src/views/Preview/index.d.ts +0 -6
- package/src/views/Preview/index.d.ts.map +0 -1
- package/src/views/Settings/SettingsView.d.ts +0 -10
- package/src/views/Settings/SettingsView.d.ts.map +0 -1
- package/src/views/Settings/index.d.ts +0 -6
- package/src/views/Settings/index.d.ts.map +0 -1
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts +0 -12
- package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +0 -1
- package/src/views/SlugSEO/index.d.ts +0 -6
- package/src/views/SlugSEO/index.d.ts.map +0 -1
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Post Manager View
|
|
3
|
-
*
|
|
4
|
-
* Follows dashboard earth-tone design system
|
|
3
|
+
* Natural scroll layout with sticky header synchronization
|
|
5
4
|
*/
|
|
6
5
|
'use client';
|
|
7
6
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
7
|
import React, { useState, useEffect } from 'react';
|
|
9
|
-
import { Plus, List, Grid3x3 } from 'lucide-react';
|
|
8
|
+
import { Plus, List, Grid3x3, Settings, Loader2, Zap } from 'lucide-react';
|
|
10
9
|
import { PostStats } from './PostStats';
|
|
11
10
|
import { PostFilters } from './PostFilters';
|
|
12
11
|
import { PostTable } from './PostTable';
|
|
13
12
|
import { PostCards } from './PostCards';
|
|
14
13
|
import { EmptyState } from './EmptyState';
|
|
15
|
-
import { apiToBlogPost } from '../../lib/mappers/apiMapper';
|
|
16
14
|
const STORAGE_KEY_PREFIX = 'blog-view-mode';
|
|
17
15
|
export function PostManagerView({ siteId, locale }) {
|
|
18
16
|
const [posts, setPosts] = useState([]);
|
|
@@ -22,7 +20,6 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
22
20
|
const [statusFilter, setStatusFilter] = useState('all');
|
|
23
21
|
const [categoryFilter, setCategoryFilter] = useState('all');
|
|
24
22
|
const [currentLanguage, setCurrentLanguage] = useState(locale || 'nl');
|
|
25
|
-
// Load view mode preference from localStorage
|
|
26
23
|
const getStoredViewMode = () => {
|
|
27
24
|
if (typeof window === 'undefined')
|
|
28
25
|
return 'list';
|
|
@@ -30,13 +27,11 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
30
27
|
return (stored === 'list' || stored === 'cards') ? stored : 'list';
|
|
31
28
|
};
|
|
32
29
|
const [viewMode, setViewMode] = useState(getStoredViewMode);
|
|
33
|
-
// Save view mode preference to localStorage when it changes
|
|
34
30
|
useEffect(() => {
|
|
35
31
|
if (typeof window !== 'undefined') {
|
|
36
32
|
localStorage.setItem(`${STORAGE_KEY_PREFIX}-${siteId}`, viewMode);
|
|
37
33
|
}
|
|
38
34
|
}, [viewMode, siteId]);
|
|
39
|
-
// Fetch posts from API
|
|
40
35
|
useEffect(() => {
|
|
41
36
|
const fetchPosts = async () => {
|
|
42
37
|
try {
|
|
@@ -44,39 +39,20 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
44
39
|
const response = await fetch(`/api/plugin-blog?admin=true&language=${currentLanguage}`);
|
|
45
40
|
const data = await response.json();
|
|
46
41
|
if (data.blogs && Array.isArray(data.blogs)) {
|
|
47
|
-
// Convert API format to PostListItem format
|
|
48
42
|
const postListItems = data.blogs.map((doc) => {
|
|
49
|
-
const blogPost = apiToBlogPost(doc);
|
|
50
|
-
// Use semantic ID (id) - plugin-images handles resolution
|
|
51
|
-
// The id is the semantic ID (e.g., "blog-featured-{slug}") which plugin-images resolves
|
|
52
|
-
const featuredImageId = blogPost.metadata.featuredImage?.id;
|
|
53
|
-
// Extract category from metadata or hero block
|
|
54
|
-
let category = undefined;
|
|
55
|
-
if (blogPost.metadata.categories && blogPost.metadata.categories.length > 0) {
|
|
56
|
-
category = blogPost.metadata.categories[0];
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// Check hero block for category
|
|
60
|
-
const heroBlock = blogPost.blocks.find(block => block.type === 'hero');
|
|
61
|
-
if (heroBlock && heroBlock.data && typeof heroBlock.data === 'object') {
|
|
62
|
-
const heroCategory = heroBlock.data.category;
|
|
63
|
-
if (heroCategory && typeof heroCategory === 'string' && heroCategory.trim()) {
|
|
64
|
-
category = heroCategory.trim();
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
43
|
return {
|
|
69
|
-
id:
|
|
70
|
-
title:
|
|
71
|
-
slug:
|
|
72
|
-
status:
|
|
73
|
-
date:
|
|
74
|
-
excerpt:
|
|
75
|
-
featuredImage:
|
|
76
|
-
authorId:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
44
|
+
id: doc.id,
|
|
45
|
+
title: doc.title,
|
|
46
|
+
slug: doc.slug,
|
|
47
|
+
status: doc.status,
|
|
48
|
+
date: doc.publication?.date,
|
|
49
|
+
excerpt: doc.summary,
|
|
50
|
+
featuredImage: doc.image?.id || doc.image?.src,
|
|
51
|
+
authorId: doc.authorId,
|
|
52
|
+
author: doc.author,
|
|
53
|
+
updatedAt: doc.updatedAt || doc.publication?.date || doc.date || new Date().toISOString(),
|
|
54
|
+
category: doc.categoryTags?.category,
|
|
55
|
+
lang: doc.lang,
|
|
80
56
|
availableLanguages: doc.availableLanguages,
|
|
81
57
|
languages: doc.languages,
|
|
82
58
|
};
|
|
@@ -94,7 +70,6 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
94
70
|
};
|
|
95
71
|
fetchPosts();
|
|
96
72
|
}, [currentLanguage]);
|
|
97
|
-
// Extract unique categories from posts
|
|
98
73
|
const categories = React.useMemo(() => {
|
|
99
74
|
const categorySet = new Set();
|
|
100
75
|
posts.forEach(post => {
|
|
@@ -104,7 +79,6 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
104
79
|
});
|
|
105
80
|
return Array.from(categorySet).sort();
|
|
106
81
|
}, [posts]);
|
|
107
|
-
// Extract unique languages from all posts
|
|
108
82
|
const availableLanguages = React.useMemo(() => {
|
|
109
83
|
const langSet = new Set();
|
|
110
84
|
posts.forEach(post => {
|
|
@@ -114,14 +88,12 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
114
88
|
if (post.lang)
|
|
115
89
|
langSet.add(post.lang);
|
|
116
90
|
});
|
|
117
|
-
// Always include the current locale/language to ensure it's selectable
|
|
118
91
|
if (locale)
|
|
119
92
|
langSet.add(locale);
|
|
120
93
|
if (currentLanguage)
|
|
121
94
|
langSet.add(currentLanguage);
|
|
122
95
|
return Array.from(langSet).sort();
|
|
123
96
|
}, [posts, locale, currentLanguage]);
|
|
124
|
-
// Filter posts
|
|
125
97
|
const filteredPosts = React.useMemo(() => {
|
|
126
98
|
return posts.filter((post) => {
|
|
127
99
|
const matchesSearch = search === '' ||
|
|
@@ -133,68 +105,30 @@ export function PostManagerView({ siteId, locale }) {
|
|
|
133
105
|
return matchesSearch && matchesStatus && matchesCategory;
|
|
134
106
|
});
|
|
135
107
|
}, [posts, search, statusFilter, categoryFilter]);
|
|
136
|
-
|
|
137
|
-
const handleCreatePost = () => {
|
|
138
|
-
// Navigate to editor route - the plugin router will handle this
|
|
139
|
-
// The route 'new' maps to the editor view
|
|
140
|
-
window.location.href = '/dashboard/blog/new';
|
|
141
|
-
};
|
|
108
|
+
const handleCreatePost = () => { window.location.href = '/dashboard/blog/new'; };
|
|
142
109
|
const handleEdit = (postId) => {
|
|
143
|
-
// Find the post to get its slug
|
|
144
110
|
const post = posts.find(p => p.id === postId);
|
|
145
|
-
if (post)
|
|
146
|
-
// Navigate to editor with slug (API uses slug, not ID)
|
|
111
|
+
if (post)
|
|
147
112
|
window.location.href = `/dashboard/blog/editor/${post.slug}`;
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
const handlePreview = (postId) => {
|
|
151
|
-
// Open preview in new tab
|
|
152
|
-
window.open(`/dashboard/blog/preview/${postId}`, '_blank');
|
|
153
|
-
};
|
|
154
|
-
const handleDuplicate = (postId) => {
|
|
155
|
-
// TODO: Implement duplicate functionality
|
|
156
|
-
const post = posts.find((p) => p.id === postId);
|
|
157
|
-
if (post) {
|
|
158
|
-
const duplicated = {
|
|
159
|
-
...post,
|
|
160
|
-
id: `duplicate-${Date.now()}`,
|
|
161
|
-
title: `${post.title} (Copy)`,
|
|
162
|
-
slug: `${post.slug}-copy-${Date.now()}`,
|
|
163
|
-
status: 'draft',
|
|
164
|
-
updatedAt: new Date().toISOString(),
|
|
165
|
-
};
|
|
166
|
-
setPosts((prev) => [...prev, duplicated]);
|
|
167
|
-
}
|
|
168
113
|
};
|
|
114
|
+
const handlePreview = (postId) => { window.open(`/dashboard/blog/preview/${postId}`, '_blank'); };
|
|
115
|
+
const handleDuplicate = (postId) => { };
|
|
169
116
|
const handleDelete = async (postId) => {
|
|
170
|
-
if (confirm('Are you sure
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (response.ok) {
|
|
178
|
-
// Remove from local state
|
|
179
|
-
setPosts((prev) => prev.filter((p) => p.id !== postId));
|
|
180
|
-
setTotalPosts(prev => prev - 1);
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
const error = await response.json();
|
|
184
|
-
alert(error.error || 'Failed to delete post');
|
|
185
|
-
}
|
|
117
|
+
if (confirm('Are you sure?')) {
|
|
118
|
+
const post = posts.find(p => p.id === postId);
|
|
119
|
+
if (post) {
|
|
120
|
+
const res = await fetch(`/api/plugin-blog/${post.slug}`, { method: 'DELETE' });
|
|
121
|
+
if (res.ok) {
|
|
122
|
+
setPosts((prev) => prev.filter((p) => p.id !== postId));
|
|
123
|
+
setTotalPosts(prev => prev - 1);
|
|
186
124
|
}
|
|
187
125
|
}
|
|
188
|
-
catch (error) {
|
|
189
|
-
console.error('Failed to delete post:', error);
|
|
190
|
-
alert('Failed to delete post');
|
|
191
|
-
}
|
|
192
126
|
}
|
|
193
127
|
};
|
|
194
128
|
const hasActiveFilters = search !== '' || statusFilter !== 'all' || categoryFilter !== 'all';
|
|
195
|
-
return (_jsxs("div", { className: "
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
129
|
+
return (_jsxs("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent", children: [_jsxs("div", { className: "flex flex-col md:flex-row md:items-end justify-between gap-8 px-2", children: [_jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "inline-flex items-center gap-2 px-3 py-1 rounded-full bg-primary/15 border border-primary/30 text-primary text-[10px] font-bold uppercase tracking-wider shadow-sm", children: [_jsx(Zap, { size: 12, className: "fill-primary animate-pulse" }), _jsx("span", { children: "Editorial Content Control" })] }), _jsxs("div", { children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Blog ", _jsx("span", { className: "text-primary", children: "&" }), " Articles"] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium max-w-md leading-relaxed opacity-80", children: "Create and manage your digital publications and stories across the ecosystem." })] })] }), _jsxs("div", { className: "flex items-center gap-4", children: [_jsx("button", { onClick: () => window.location.href = '/dashboard/blog/settings', className: "p-3.5 bg-dashboard-card/50 border border-dashboard-border/40 text-dashboard-text-secondary rounded-2xl hover:text-primary hover:border-primary/30 transition-all active:scale-95 shadow-sm", title: "Blog Settings", children: _jsx(Settings, { size: 18 }) }), _jsxs("button", { onClick: handleCreatePost, className: "group relative flex items-center gap-3 px-7 py-3.5 bg-primary text-white rounded-2xl text-[10px] font-bold uppercase tracking-widest overflow-hidden transition-all hover:scale-[1.02] active:scale-95 shadow-lg shadow-primary/20", children: [_jsx(Plus, { size: 18, className: "relative z-10" }), _jsx("span", { className: "relative z-10", children: "Add New Post" })] })] })] }), _jsx("div", { className: "px-2", children: _jsx(PostStats, { total: totalPosts, posts: posts }) }), _jsx("div", { className: "sticky top-[-40px] lg:top-[-40px] z-40 bg-dashboard-bg/40 backdrop-blur-xl border-y border-dashboard-border/40 py-4 px-2 ml-[-8px] mr-[-8px]", children: _jsxs("div", { className: "flex flex-col lg:flex-row items-center gap-4", children: [_jsx(PostFilters, { search: search, onSearchChange: setSearch, statusFilter: statusFilter, onStatusFilterChange: setStatusFilter, categoryFilter: categoryFilter, onCategoryFilterChange: setCategoryFilter, categories: categories, language: currentLanguage, onLanguageChange: setCurrentLanguage, availableLanguages: availableLanguages }), _jsxs("div", { className: "flex items-center gap-1.5 p-1.5 bg-dashboard-card/50 rounded-xl border border-dashboard-border/40", children: [_jsx("button", { onClick: () => setViewMode('list'), className: `p-2.5 rounded-lg transition-all ${viewMode === 'list'
|
|
130
|
+
? 'bg-primary text-white shadow-lg shadow-primary/20'
|
|
131
|
+
: 'text-dashboard-text-secondary hover:text-primary hover:bg-primary/5'}`, title: "List View", children: _jsx(List, { size: 18 }) }), _jsx("button", { onClick: () => setViewMode('cards'), className: `p-2.5 rounded-lg transition-all ${viewMode === 'cards'
|
|
132
|
+
? 'bg-primary text-white shadow-lg shadow-primary/20'
|
|
133
|
+
: 'text-dashboard-text-secondary hover:text-primary hover:bg-primary/5'}`, title: "Card View", children: _jsx(Grid3x3, { size: 18 }) })] })] }) }), _jsx("div", { className: "px-2 min-h-[400px] pb-32", children: loading ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-32 gap-4", children: [_jsx(Loader2, { className: "animate-spin text-primary opacity-40", size: 40 }), _jsx("p", { className: "text-[10px] font-bold text-primary uppercase tracking-widest animate-pulse", children: "Loading Publications" })] })) : filteredPosts.length === 0 ? (_jsx(EmptyState, { hasFilters: hasActiveFilters, onCreatePost: handleCreatePost })) : viewMode === 'list' ? (_jsx(PostTable, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete })) : (_jsx(PostCards, { posts: filteredPosts, locale: locale, onEdit: handleEdit, onPreview: handlePreview, onDuplicate: handleDuplicate, onDelete: handleDelete })) })] }));
|
|
200
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostStats.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostStats.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"PostStats.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostStats.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,cAAc,2CAgEzD"}
|
|
@@ -14,33 +14,33 @@ export function PostStats({ total, posts }) {
|
|
|
14
14
|
label: 'Total Posts',
|
|
15
15
|
value: total,
|
|
16
16
|
icon: FileText,
|
|
17
|
-
color: 'text-
|
|
18
|
-
|
|
17
|
+
color: 'text-primary',
|
|
18
|
+
accent: 'bg-primary',
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
label: 'Published',
|
|
22
22
|
value: published,
|
|
23
23
|
icon: CheckCircle2,
|
|
24
|
-
color: 'text-
|
|
25
|
-
|
|
24
|
+
color: 'text-emerald-500',
|
|
25
|
+
accent: 'bg-emerald-500',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
label: 'Drafts',
|
|
29
29
|
value: drafts,
|
|
30
30
|
icon: Clock,
|
|
31
|
-
color: 'text-amber-
|
|
32
|
-
|
|
31
|
+
color: 'text-amber-500',
|
|
32
|
+
accent: 'bg-amber-500',
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
label: 'Scheduled',
|
|
36
36
|
value: scheduled,
|
|
37
37
|
icon: Archive,
|
|
38
|
-
color: 'text-blue-
|
|
39
|
-
|
|
38
|
+
color: 'text-blue-500',
|
|
39
|
+
accent: 'bg-blue-500',
|
|
40
40
|
},
|
|
41
41
|
];
|
|
42
|
-
return (_jsx("div", { className: "grid grid-cols-2
|
|
42
|
+
return (_jsx("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-5", children: stats.map((stat) => {
|
|
43
43
|
const Icon = stat.icon;
|
|
44
|
-
return (
|
|
44
|
+
return (_jsxs("div", { className: "bg-dashboard-card/50 border border-dashboard-border/40 p-5 rounded-2xl relative overflow-hidden group transition-all duration-500", children: [_jsx("div", { className: `absolute top-0 right-0 p-4 opacity-5 group-hover:scale-105 transition-all duration-700 ${stat.color}`, children: _jsx(Icon, { size: 80 }) }), _jsxs("div", { className: "relative z-10", children: [_jsxs("div", { className: "flex items-center gap-2 mb-1", children: [_jsx("div", { className: `size-1.5 rounded-full ${stat.accent} animate-pulse shadow-[0_0_8px_rgba(var(--color-primary),0.5)]` }), _jsx("label", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest block opacity-80", children: stat.label })] }), _jsx("p", { className: `text-3xl font-bold tracking-tight ${stat.color}`, children: stat.value })] })] }, stat.label));
|
|
45
45
|
}) }));
|
|
46
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PostTable.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostTable.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAK5D,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AA4BD,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,WAAW,EACX,QAAQ,GACX,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"PostTable.d.ts","sourceRoot":"","sources":["../../../src/views/PostManager/PostTable.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAK5D,MAAM,WAAW,cAAc;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AA4BD,wBAAgB,SAAS,CAAC,EACtB,KAAK,EACL,MAAM,EACN,MAAM,EACN,SAAS,EACT,WAAW,EACX,QAAQ,GACX,EAAE,cAAc,2CA2JhB"}
|
|
@@ -4,26 +4,25 @@
|
|
|
4
4
|
*/
|
|
5
5
|
'use client';
|
|
6
6
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { Image } from '@jhits/plugin-images';
|
|
7
|
+
import { FileText, Tag } from 'lucide-react';
|
|
8
|
+
import { Image as PluginImage } from '@jhits/plugin-images';
|
|
10
9
|
import { PostActionsMenu } from './PostActionsMenu';
|
|
11
10
|
import { LanguageFlags } from './LanguageFlags';
|
|
12
11
|
import { useSession } from 'next-auth/react';
|
|
13
12
|
function getStatusBadgeColor(status) {
|
|
14
13
|
switch (status) {
|
|
15
14
|
case 'published':
|
|
16
|
-
return 'bg-
|
|
15
|
+
return 'bg-emerald-500 text-white border-emerald-400 shadow-sm';
|
|
17
16
|
case 'draft':
|
|
18
|
-
return 'bg-amber-500
|
|
17
|
+
return 'bg-amber-500 text-white border-amber-400 shadow-sm';
|
|
19
18
|
case 'scheduled':
|
|
20
|
-
return 'bg-blue-500
|
|
19
|
+
return 'bg-blue-500 text-white border-blue-400 shadow-sm';
|
|
21
20
|
case 'archived':
|
|
22
|
-
return 'bg-neutral-500
|
|
21
|
+
return 'bg-neutral-500 text-white border-neutral-400';
|
|
23
22
|
case 'not-translated':
|
|
24
|
-
return 'bg-red-500/10 text-red-
|
|
23
|
+
return 'bg-red-500/10 text-red-500 border-red-500/20 italic';
|
|
25
24
|
default:
|
|
26
|
-
return 'bg-neutral-500/10 text-neutral-
|
|
25
|
+
return 'bg-neutral-500/10 text-neutral-500 border-neutral-500/20';
|
|
27
26
|
}
|
|
28
27
|
}
|
|
29
28
|
function formatDate(dateString, locale) {
|
|
@@ -38,43 +37,27 @@ function formatDate(dateString, locale) {
|
|
|
38
37
|
export function PostTable({ posts, locale, onEdit, onPreview, onDuplicate, onDelete, }) {
|
|
39
38
|
const { data: session, status: sessionStatus } = useSession();
|
|
40
39
|
const currentUserId = session?.user?.id;
|
|
41
|
-
const [userMap, setUserMap] = useState({});
|
|
42
40
|
// Helper function to check if user is the owner
|
|
43
41
|
const isPostOwner = (post) => {
|
|
44
42
|
if (sessionStatus === 'loading')
|
|
45
|
-
return false;
|
|
43
|
+
return false;
|
|
46
44
|
if (!currentUserId || !post.authorId)
|
|
47
45
|
return false;
|
|
48
|
-
// Convert both to strings for comparison to handle ObjectId vs string
|
|
49
46
|
return String(currentUserId) === String(post.authorId);
|
|
50
47
|
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
users.forEach((user) => {
|
|
60
|
-
const id = user._id?.toString();
|
|
61
|
-
if (id) {
|
|
62
|
-
map[id] = user.name || user.email || 'Unknown';
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
setUserMap(map);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
console.error('Failed to fetch users:', error);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
fetchUsers();
|
|
73
|
-
}, []);
|
|
74
|
-
const getAuthorName = (authorId) => {
|
|
75
|
-
if (!authorId)
|
|
76
|
-
return 'Unknown';
|
|
77
|
-
return userMap[authorId] || authorId;
|
|
48
|
+
const getAuthorData = (post) => {
|
|
49
|
+
if (post.author) {
|
|
50
|
+
return {
|
|
51
|
+
name: post.author.name || 'Unknown Author',
|
|
52
|
+
image: post.author.image
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return { name: 'Unknown Author' };
|
|
78
56
|
};
|
|
79
|
-
return (_jsx("div", { className: "bg-
|
|
57
|
+
return (_jsx("div", { className: "bg-dashboard-card/40 rounded-[2rem] overflow-hidden border border-dashboard-border/40 shadow-sm", children: _jsx("div", { className: "overflow-x-auto custom-scrollbar", children: _jsxs("table", { className: "w-full text-left border-collapse min-w-[1000px] lg:min-w-0", children: [_jsx("thead", { children: _jsxs("tr", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest border-b border-dashboard-border/40 bg-dashboard-bg/20", children: [_jsx("th", { className: "px-8 py-5", children: "Publication" }), _jsx("th", { className: "px-8 py-5 hidden lg:table-cell", children: "Author" }), _jsx("th", { className: "px-8 py-5 hidden xl:table-cell", children: "Category" }), _jsx("th", { className: "px-8 py-5", children: "Editions" }), _jsx("th", { className: "px-8 py-5", children: "Status" }), _jsx("th", { className: "px-8 py-5 hidden md:table-cell", children: "Modified" }), _jsx("th", { className: "px-8 py-5 text-right", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-dashboard-border/30", children: posts.map((post) => {
|
|
58
|
+
const owner = isPostOwner(post);
|
|
59
|
+
const author = getAuthorData(post);
|
|
60
|
+
const initials = author.name.split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2);
|
|
61
|
+
return (_jsxs("tr", { className: "group hover:bg-primary/[0.03] transition-colors", children: [_jsx("td", { className: "px-8 py-4", children: _jsxs("div", { className: "flex items-center gap-4", children: [post.featuredImage ? (_jsx("div", { className: `size-12 relative bg-dashboard-bg/50 rounded-xl overflow-hidden border transition-all shrink-0 ${owner ? 'border-primary/30' : 'border-dashboard-border/60'}`, children: _jsx(PluginImage, { id: post.featuredImage, alt: post.title, fill: true, editable: false, className: "object-cover" }) })) : (_jsx("div", { className: "size-12 rounded-xl bg-dashboard-bg/50 flex items-center justify-center border border-dashboard-border/60 opacity-20 shrink-0", children: _jsx(FileText, { size: 18 }) })), _jsxs("div", { className: "min-w-0", children: [_jsx("button", { onClick: () => onEdit(post.id), className: "text-left w-full hover:cursor-pointer p-0 m-0 border-0 bg-transparent group/title", children: _jsx("h3", { className: "font-bold text-dashboard-text text-sm tracking-tight group-hover/title:text-primary transition-colors truncate max-w-[200px] lg:max-w-[300px]", children: post.title.trim() }) }), _jsxs("p", { className: "text-[9px] font-mono text-dashboard-text-secondary/50 uppercase tracking-tight truncate max-w-[150px]", children: ["/", post.slug] })] })] }) }), _jsx("td", { className: "px-8 py-4 hidden lg:table-cell", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: `size-8 rounded-lg flex items-center justify-center text-[10px] font-bold border transition-all overflow-hidden shrink-0 ${owner ? 'bg-primary text-white border-primary/20 shadow-lg shadow-primary/20' : 'bg-dashboard-bg/50 text-dashboard-text-secondary border-dashboard-border/60'}`, children: author.image ? (_jsx("img", { src: author.image, alt: author.name, className: "size-full object-cover", crossOrigin: "anonymous" })) : initials }), _jsxs("span", { className: `text-[10px] font-bold uppercase tracking-tight truncate max-w-[100px] ${owner ? 'text-primary' : 'text-dashboard-text/70'}`, children: [author.name, owner && _jsx("span", { className: "opacity-60 ml-0.5", children: "(YOU)" })] })] }) }), _jsx("td", { className: "px-8 py-4 hidden xl:table-cell", children: _jsxs("span", { className: "text-[10px] font-bold text-primary/80 uppercase tracking-widest flex items-center gap-1.5", children: [_jsx(Tag, { size: 10 }), post.category || 'Article'] }) }), _jsx("td", { className: "px-8 py-4", children: _jsx(LanguageFlags, { post: post }) }), _jsx("td", { className: "px-8 py-4", children: _jsx("span", { className: `inline-flex items-center px-3 py-1 rounded-full text-[9px] font-bold uppercase tracking-wider border backdrop-blur-sm shadow-sm ${getStatusBadgeColor(post.status)}`, children: post.status === 'not-translated' ? 'Edition Missing' : post.status }) }), _jsx("td", { className: "px-8 py-4 hidden md:table-cell", children: _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-[11px] font-semibold text-dashboard-text/80 uppercase tracking-tight", children: formatDate(post.updatedAt, locale) }), _jsx("span", { className: "text-[9px] font-bold text-dashboard-text-secondary/50 uppercase tracking-widest", children: "Last Edit" })] }) }), _jsx("td", { className: "px-8 py-4 text-right", children: owner ? (_jsx("div", { className: "flex items-center justify-end", children: _jsx(PostActionsMenu, { onEdit: () => onEdit(post.id), onPreview: () => onPreview(post.id), onDuplicate: () => onDuplicate(post.id), onDelete: () => onDelete(post.id) }) })) : (_jsx("span", { className: "text-[9px] font-bold text-dashboard-text-secondary/30 uppercase tracking-widest italic", children: "View Only" })) })] }, post.id));
|
|
62
|
+
}) })] }) }) }));
|
|
80
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SettingsView.d.ts","sourceRoot":"","sources":["../../../src/views/Settings/SettingsView.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"SettingsView.d.ts","sourceRoot":"","sources":["../../../src/views/Settings/SettingsView.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,iBAAiB,2CAsKjE"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Settings View -
|
|
2
|
+
* Settings View - Theme Configuration
|
|
3
3
|
* Allows manual configuration of plugin settings (darkMode, backgroundColors)
|
|
4
4
|
*/
|
|
5
5
|
'use client';
|
|
@@ -45,50 +45,31 @@ export function SettingsView({ siteId, locale }) {
|
|
|
45
45
|
const handleSave = () => {
|
|
46
46
|
if (typeof window === 'undefined')
|
|
47
47
|
return;
|
|
48
|
-
// Initialize window global if needed
|
|
49
|
-
if (!window.__JHITS_PLUGIN_PROPS__) {
|
|
50
|
-
window.__JHITS_PLUGIN_PROPS__ = {};
|
|
51
|
-
}
|
|
52
48
|
// Update configuration
|
|
53
|
-
|
|
54
|
-
...(window.__JHITS_PLUGIN_PROPS__['plugin-blog'] || {}),
|
|
49
|
+
const config = {
|
|
55
50
|
darkMode,
|
|
56
51
|
backgroundColors: {
|
|
57
52
|
light: lightBg,
|
|
58
53
|
dark: darkBg,
|
|
59
54
|
},
|
|
60
55
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
localStorage.setItem('__JHITS_PLUGIN_BLOG_CONFIG__', JSON.stringify({
|
|
64
|
-
darkMode,
|
|
65
|
-
backgroundColors: {
|
|
66
|
-
light: lightBg,
|
|
67
|
-
dark: darkBg,
|
|
68
|
-
},
|
|
69
|
-
}));
|
|
70
|
-
}
|
|
71
|
-
catch (e) {
|
|
72
|
-
console.warn('[SettingsView] Failed to save to localStorage:', e);
|
|
56
|
+
if (!window.__JHITS_PLUGIN_PROPS__) {
|
|
57
|
+
window.__JHITS_PLUGIN_PROPS__ = {};
|
|
73
58
|
}
|
|
59
|
+
window.__JHITS_PLUGIN_PROPS__['plugin-blog'] = {
|
|
60
|
+
...(window.__JHITS_PLUGIN_PROPS__['plugin-blog'] || {}),
|
|
61
|
+
...config
|
|
62
|
+
};
|
|
63
|
+
localStorage.setItem('__JHITS_PLUGIN_BLOG_CONFIG__', JSON.stringify(config));
|
|
74
64
|
setSaved(true);
|
|
75
65
|
setTimeout(() => setSaved(false), 2000);
|
|
76
|
-
|
|
77
|
-
window.dispatchEvent(new CustomEvent('blog-plugin-config-updated', {
|
|
78
|
-
detail: { darkMode, backgroundColors: { light: lightBg, dark: darkBg } }
|
|
79
|
-
}));
|
|
80
|
-
console.log('[SettingsView] Configuration saved:', {
|
|
81
|
-
darkMode,
|
|
82
|
-
backgroundColors: { light: lightBg, dark: darkBg },
|
|
83
|
-
});
|
|
66
|
+
window.dispatchEvent(new CustomEvent('blog-plugin-config-updated', { detail: config }));
|
|
84
67
|
};
|
|
85
|
-
// Reset to defaults
|
|
86
68
|
const handleReset = () => {
|
|
87
69
|
setDarkMode(true);
|
|
88
70
|
setLightBg('#ffffff');
|
|
89
71
|
setDarkBg('#171717');
|
|
90
72
|
};
|
|
91
|
-
// Load from localStorage on mount
|
|
92
73
|
useEffect(() => {
|
|
93
74
|
try {
|
|
94
75
|
const saved = localStorage.getItem('__JHITS_PLUGIN_BLOG_CONFIG__');
|
|
@@ -99,15 +80,7 @@ export function SettingsView({ siteId, locale }) {
|
|
|
99
80
|
setDarkBg(config.backgroundColors?.dark ?? '#171717');
|
|
100
81
|
}
|
|
101
82
|
}
|
|
102
|
-
catch (e) {
|
|
103
|
-
console.warn('[SettingsView] Failed to load from localStorage:', e);
|
|
104
|
-
}
|
|
83
|
+
catch (e) { }
|
|
105
84
|
}, []);
|
|
106
|
-
return (_jsx("div", { className: "
|
|
107
|
-
? 'bg-primary'
|
|
108
|
-
: 'bg-neutral-300 dark:bg-neutral-600'}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${darkMode ? 'translate-x-6' : 'translate-x-1'}` }) })] }) }), _jsxs("div", { className: "mb-8", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Palette, { className: "size-5 text-neutral-600 dark:text-neutral-400" }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Background Colors" }), _jsx("p", { className: "text-xs text-neutral-500 dark:text-neutral-500 mt-1", children: "Set custom background colors for the editor canvas" })] })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsxs("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-2", children: ["Light Mode Background ", _jsx("span", { className: "text-red-500", children: "*" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "text", value: lightBg, onChange: (e) => setLightBg(e.target.value), placeholder: "#ffffff", className: "flex-1 bg-dashboard-card border border-dashboard-border p-4 rounded-2xl text-sm font-bold outline-none focus:border-primary transition-all text-dashboard-text" }), _jsx("div", { className: "w-16 h-16 rounded-xl border-2 border-neutral-200 dark:border-neutral-700", style: { backgroundColor: lightBg } })] }), _jsx("p", { className: "text-xs text-neutral-400 dark:text-neutral-600 mt-1", children: "CSS color value (hex, rgb, or named color)" })] }), _jsxs("div", { children: [_jsxs("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-2", children: ["Dark Mode Background ", _jsx("span", { className: "text-neutral-400", children: "(Optional)" })] }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("input", { type: "text", value: darkBg, onChange: (e) => setDarkBg(e.target.value), placeholder: "#171717", disabled: !darkMode, className: `flex-1 bg-white dark:bg-neutral-900/50 border border-neutral-300 dark:border-neutral-700 p-4 rounded-2xl text-sm font-bold outline-none focus:border-primary transition-all dark:text-neutral-100 ${!darkMode ? 'opacity-50 cursor-not-allowed' : ''}` }), _jsx("div", { className: `w-16 h-16 rounded-xl border-2 border-neutral-200 dark:border-neutral-700 ${!darkMode ? 'opacity-50' : ''}`, style: { backgroundColor: darkBg } })] }), _jsx("p", { className: "text-xs text-neutral-400 dark:text-neutral-600 mt-1", children: "Only used when dark mode is enabled" })] })] })] }), _jsxs("div", { className: "mb-8 p-6 bg-neutral-50 dark:bg-neutral-900/50 rounded-2xl border border-neutral-200 dark:border-neutral-700", children: [_jsx("label", { className: "block text-[10px] font-black uppercase tracking-widest text-neutral-500 dark:text-neutral-500 mb-3", children: "Preview" }), _jsx("div", { className: "h-32 rounded-xl border-2 border-dashed border-neutral-300 dark:border-neutral-700 flex items-center justify-center", style: {
|
|
109
|
-
backgroundColor: darkMode ? darkBg : lightBg,
|
|
110
|
-
}, children: _jsx("span", { className: "text-xs font-bold uppercase tracking-widest text-neutral-600 dark:text-neutral-400", children: "Editor Canvas Preview" }) })] }), _jsxs("div", { className: "flex items-center justify-between pt-6 border-t border-neutral-200 dark:border-neutral-700", children: [_jsxs("button", { onClick: handleReset, className: "px-6 py-3 rounded-full border border-neutral-300 dark:border-neutral-700 bg-white dark:bg-neutral-900/50 text-sm font-black uppercase tracking-widest text-neutral-600 dark:text-neutral-400 hover:bg-neutral-50 dark:hover:bg-neutral-800 transition-colors flex items-center gap-2", children: [_jsx(RotateCcw, { className: "size-4" }), "Reset"] }), _jsxs("button", { onClick: handleSave, disabled: !hasChanges, className: `px-6 py-3 rounded-full text-sm font-black uppercase tracking-widest transition-all flex items-center gap-2 ${hasChanges
|
|
111
|
-
? 'bg-primary text-white hover:bg-primary/90 shadow-lg shadow-primary/20'
|
|
112
|
-
: 'bg-neutral-200 dark:bg-neutral-700 text-neutral-400 dark:text-neutral-600 cursor-not-allowed'}`, children: [_jsx(Save, { className: "size-4" }), saved ? 'Saved!' : 'Save Changes'] })] })] }), _jsxs("div", { className: "mt-6 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-2xl p-6", children: [_jsx("h3", { className: "text-sm font-black uppercase tracking-widest text-blue-900 dark:text-blue-300 mb-2", children: "How It Works" }), _jsxs("ul", { className: "text-xs text-blue-800 dark:text-blue-400 space-y-1 list-disc list-inside", children: [_jsxs("li", { children: ["Changes are saved to ", _jsx("code", { className: "bg-blue-100 dark:bg-blue-900/50 px-1 rounded", children: "window.__JHITS_PLUGIN_PROPS__" }), " and localStorage"] }), _jsx("li", { children: "Configuration persists across page refreshes" }), _jsx("li", { children: "To apply changes in the editor, navigate to a post editor page" }), _jsx("li", { children: "For production, configure these settings in your client app's blog config file" })] })] })] }) }));
|
|
85
|
+
return (_jsx("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "mb-8 px-2", children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Blog ", _jsx("span", { className: "text-primary italic", children: "Configuration" })] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium opacity-80", children: "Customize your editorial environment and visual preferences." })] }), _jsxs("div", { className: "bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm p-8 lg:p-10", children: [_jsx("div", { className: "mb-10 pb-8 border-b border-dashboard-border/30", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsx("div", { className: "size-10 rounded-xl bg-primary/10 flex items-center justify-center text-primary border border-primary/20", children: darkMode ? _jsx(Moon, { size: 20 }) : _jsx(Sun, { size: 20 }) }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-bold text-dashboard-text uppercase tracking-wider block", children: "Visual Mode" }), _jsx("p", { className: "text-xs text-dashboard-text-secondary mt-0.5 opacity-70", children: "Synchronize editor with system preference" })] })] }), _jsx("button", { onClick: () => setDarkMode(!darkMode), className: `relative inline-flex h-6 w-11 items-center rounded-full transition-all ${darkMode ? 'bg-primary shadow-lg shadow-primary/20' : 'bg-neutral-300 dark:bg-neutral-700'}`, children: _jsx("span", { className: `inline-block h-4 w-4 transform rounded-full bg-white transition-transform ${darkMode ? 'translate-x-6' : 'translate-x-1'}` }) })] }) }), _jsxs("div", { className: "mb-10", children: [_jsxs("div", { className: "flex items-center gap-4 mb-8", children: [_jsx("div", { className: "size-10 rounded-xl bg-amber-500/10 flex items-center justify-center text-amber-500 border border-amber-500/20", children: _jsx(Palette, { size: 20 }) }), _jsx("label", { className: "text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Canvas Aesthetics" })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-8", children: [_jsxs("div", { className: "space-y-3", children: [_jsx("label", { className: "block text-[10px] font-bold uppercase tracking-[0.2em] text-dashboard-text-secondary ml-1 opacity-60 text-primary", children: "Light Protocol" }), _jsx("input", { type: "text", value: lightBg, onChange: e => setLightBg(e.target.value), className: "w-full bg-dashboard-bg/50 border border-dashboard-border/40 p-4 rounded-2xl text-sm font-semibold outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 text-dashboard-text transition-all" })] }), _jsxs("div", { className: "space-y-3", children: [_jsx("label", { className: "block text-[10px] font-bold uppercase tracking-[0.2em] text-dashboard-text-secondary ml-1 opacity-60 text-primary", children: "Dark Protocol" }), _jsx("input", { type: "text", value: darkBg, onChange: e => setDarkBg(e.target.value), disabled: !darkMode, className: "w-full bg-dashboard-bg/50 border border-dashboard-border/40 p-4 rounded-2xl text-sm font-semibold outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 text-dashboard-text disabled:opacity-30 transition-all" })] })] })] }), _jsxs("div", { className: "flex items-center justify-between pt-8 border-t border-dashboard-border/30", children: [_jsxs("button", { onClick: handleReset, className: "px-6 py-3.5 rounded-2xl border border-dashboard-border/60 text-xs font-bold uppercase tracking-widest text-dashboard-text-secondary hover:text-dashboard-text hover:bg-dashboard-bg/50 transition-all active:scale-95", children: [_jsx(RotateCcw, { size: 14, className: "inline mr-2" }), " Restore Factory"] }), _jsxs("button", { onClick: handleSave, disabled: !hasChanges, className: `px-8 py-3.5 rounded-2xl text-xs font-bold uppercase tracking-widest transition-all flex items-center gap-2 ${hasChanges ? 'bg-primary text-white shadow-xl shadow-primary/25 hover:scale-[1.02]' : 'bg-neutral-100 dark:bg-neutral-800 text-dashboard-text-secondary opacity-40 cursor-not-allowed'}`, children: [_jsx(Save, { size: 16 }), " ", saved ? 'System Updated' : 'Commit Changes'] })] })] })] }) }));
|
|
113
86
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SlugSEOManagerView.d.ts","sourceRoot":"","sources":["../../../src/views/SlugSEO/SlugSEOManagerView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,uBAAuB,
|
|
1
|
+
{"version":3,"file":"SlugSEOManagerView.d.ts","sourceRoot":"","sources":["../../../src/views/SlugSEO/SlugSEOManagerView.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,MAAM,WAAW,uBAAuB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,uBAAuB,2CA2FrF"}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
'use client';
|
|
7
7
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
8
|
-
import { Search, Link2, FileText } from 'lucide-react';
|
|
8
|
+
import { Search, Link2, FileText, Globe } from 'lucide-react';
|
|
9
9
|
export function SlugSEOManagerView({ postId, siteId, locale }) {
|
|
10
|
-
return (_jsx("div", { className: "
|
|
10
|
+
return (_jsx("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 bg-transparent overflow-y-auto", children: _jsxs("div", { className: "max-w-4xl", children: [_jsxs("div", { className: "mb-8 px-2", children: [_jsxs("h1", { className: "text-4xl font-bold text-dashboard-text tracking-tight leading-none mb-2", children: ["Search ", _jsx("span", { className: "text-primary italic", children: "&" }), " Discovery"] }), _jsx("p", { className: "text-sm text-dashboard-text-secondary font-medium opacity-80", children: postId ? `Optimizing visibility for: ${postId}` : 'Manage URL architecture and search engine metadata' })] }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(Link2, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "URL Identifier" })] }), _jsx("div", { className: "flex items-center gap-3", children: _jsx("input", { type: "text", placeholder: "article-url-slug", className: "flex-1 px-5 py-4 bg-dashboard-bg/50 border border-dashboard-border/40 rounded-2xl text-sm font-semibold text-dashboard-text outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 transition-all" }) }), _jsx("p", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest mt-3 ml-1 opacity-50", children: "Automatic collision detection active" })] }), _jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(Search, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Search Engine Preview" })] }), _jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl p-6 border border-neutral-200 dark:border-neutral-800 shadow-inner", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx("div", { className: "size-4 rounded-full bg-neutral-100 dark:bg-neutral-800 flex items-center justify-center", children: _jsx(Globe, { size: 10, className: "text-neutral-400" }) }), _jsx("span", { className: "text-[10px] font-bold text-neutral-400 uppercase tracking-widest", children: "Global Result" })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("h3", { className: "text-xl text-blue-600 dark:text-blue-400 font-medium hover:underline cursor-pointer leading-tight", children: "Publication Title Will Appear Here" }), _jsx("p", { className: "text-sm text-emerald-700 dark:text-emerald-500 font-medium", children: "https://yourdomain.com/blog/article-url-slug" }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 line-clamp-2", children: "Meta description will appear here. This is the snippet users see when discovering your content via search protocols." })] })] })] }), _jsxs("div", { className: "p-8 bg-dashboard-card/40 backdrop-blur-xl rounded-[2.5rem] border border-dashboard-border/40 shadow-sm", children: [_jsxs("div", { className: "flex items-center gap-3 mb-4 ml-1", children: [_jsx(FileText, { className: "text-primary size-5" }), _jsx("label", { className: "block text-sm font-bold text-dashboard-text uppercase tracking-wider", children: "Metadata Summary" })] }), _jsx("div", { className: "flex items-start gap-3", children: _jsx("textarea", { placeholder: "Enter meta description for indexing...", rows: 4, className: "flex-1 px-5 py-4 bg-dashboard-bg/50 border border-dashboard-border/40 rounded-2xl text-sm font-semibold text-dashboard-text outline-none focus:ring-2 focus:ring-primary/20 focus:border-primary/30 transition-all resize-none" }) }), _jsxs("div", { className: "flex justify-between items-center mt-3 px-1", children: [_jsx("p", { className: "text-[10px] font-bold text-dashboard-text-secondary uppercase tracking-widest opacity-50", children: "Recommended: 150-160 characters" }), _jsx("span", { className: "text-[10px] font-bold text-primary uppercase tracking-widest", children: "0 / 160" })] })] })] })] }) }));
|
|
11
11
|
}
|