@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,7 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import React, { useState } from 'react';
|
|
4
|
-
import { ArrowLeft, Library, Settings2, Save, Clock, Edit, Eye, Globe, Plus, ChevronDown } from 'lucide-react';
|
|
4
|
+
import { ArrowLeft, Library, Settings2, Save, Clock, Edit, Eye, Globe, Plus, ChevronDown, CheckCircle2 } from 'lucide-react';
|
|
5
5
|
import { useEditor } from '../../state/EditorContext';
|
|
6
6
|
import { SaveConfirmationModal } from './SaveConfirmationModal';
|
|
7
7
|
|
|
@@ -61,268 +61,249 @@ export function EditorHeader({
|
|
|
61
61
|
es: 'Español',
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
const
|
|
64
|
+
const getFlagUrl = (lang: string) => {
|
|
65
|
+
const mapping: Record<string, string> = {
|
|
66
|
+
en: 'gb', nl: 'nl', sv: 'se', de: 'de', fr: 'fr', es: 'es'
|
|
67
|
+
};
|
|
68
|
+
return `https://flagcdn.com/w40/${(mapping[lang] || lang).toLowerCase()}.png`;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const allCreatedLanguages = Array.from(new Set([...languages, currentLanguage]));
|
|
72
|
+
const availableToAdd = ['en', 'nl', 'sv', 'de', 'fr', 'es'].filter(lang => !allCreatedLanguages.includes(lang));
|
|
73
|
+
|
|
74
|
+
|
|
65
75
|
|
|
66
76
|
const handleSaveDraftClick = () => {
|
|
67
77
|
setSaveAsDraft(true);
|
|
68
|
-
setSaveError(null);
|
|
78
|
+
setSaveError(null);
|
|
69
79
|
setShowConfirmModal(true);
|
|
70
80
|
};
|
|
71
81
|
|
|
72
82
|
const handlePublishClick = () => {
|
|
73
83
|
setSaveAsDraft(false);
|
|
74
|
-
setSaveError(null);
|
|
84
|
+
setSaveError(null);
|
|
75
85
|
setShowConfirmModal(true);
|
|
76
86
|
};
|
|
77
87
|
|
|
78
88
|
const handleConfirmSave = async () => {
|
|
79
89
|
try {
|
|
80
|
-
const targetStatus = saveAsDraft ? 'draft' : 'published';
|
|
81
|
-
console.log('[EditorHeader] Starting save process...', { saveAsDraft, targetStatus, currentStatus: state.status });
|
|
82
|
-
|
|
83
|
-
// Set status before saving - ensure state is updated
|
|
84
90
|
if (saveAsDraft) {
|
|
85
91
|
dispatch({ type: 'SET_STATUS', payload: 'draft' });
|
|
86
92
|
} else {
|
|
87
93
|
dispatch({ type: 'SET_STATUS', payload: 'published' });
|
|
88
94
|
}
|
|
89
|
-
|
|
90
|
-
// Wait longer to ensure state update propagates through the reducer and context
|
|
91
|
-
// React state updates are asynchronous, so we need to wait for the state to actually update
|
|
92
95
|
await new Promise(resolve => setTimeout(resolve, 150));
|
|
93
|
-
|
|
94
|
-
// Verify status was updated
|
|
95
|
-
console.log('[EditorHeader] Status after update:', state.status, 'Expected:', targetStatus);
|
|
96
|
-
|
|
97
96
|
await onSave(!saveAsDraft);
|
|
98
|
-
console.log('[EditorHeader] Post saved successfully');
|
|
99
|
-
// Clear any previous errors
|
|
100
97
|
setSaveError(null);
|
|
101
|
-
// Modal will show success message and close automatically
|
|
102
98
|
} catch (error: any) {
|
|
103
|
-
console.error('[EditorHeader] Failed to save post:', error);
|
|
104
|
-
// Extract user-friendly error message
|
|
105
99
|
let errorMessage = error.message || 'Failed to save post';
|
|
106
|
-
|
|
107
|
-
// Make error messages more user-friendly
|
|
108
|
-
if (errorMessage.includes('Missing required fields')) {
|
|
109
|
-
// Keep the detailed message about missing fields
|
|
110
|
-
errorMessage = errorMessage.replace('Missing required fields for publishing:', 'To publish, please fill in:');
|
|
111
|
-
} else if (errorMessage.includes('All required fields')) {
|
|
112
|
-
errorMessage = 'To publish, please fill in all required fields: summary, featured image, category, and content.';
|
|
113
|
-
} else if (errorMessage.includes('Unauthorized')) {
|
|
114
|
-
errorMessage = 'You are not authorized to save this post. Please log in again.';
|
|
115
|
-
} else if (errorMessage.includes('Failed to save')) {
|
|
116
|
-
errorMessage = 'Unable to save the post. Please check your connection and try again.';
|
|
117
|
-
}
|
|
118
|
-
|
|
119
100
|
setSaveError(errorMessage);
|
|
120
101
|
onSaveError(errorMessage);
|
|
121
|
-
// Re-throw the error so the modal knows it failed and doesn't show success
|
|
122
102
|
throw error;
|
|
123
103
|
}
|
|
124
104
|
};
|
|
125
105
|
|
|
126
106
|
return (
|
|
127
|
-
<div className="flex items-center justify-between px-
|
|
128
|
-
|
|
107
|
+
<div className="flex items-center justify-between px-4 lg:px-8 py-3 lg:py-4 bg-dashboard-bg/80 backdrop-blur-xl border-b border-dashboard-border/50 flex-none shrink-0 z-50">
|
|
108
|
+
{/* Left Section: Navigation & Library */}
|
|
109
|
+
<div className="flex items-center gap-3 lg:gap-6">
|
|
129
110
|
<button
|
|
130
111
|
onClick={() => {
|
|
131
112
|
if (isDirty) {
|
|
132
|
-
|
|
133
|
-
'You have unsaved changes. Are you sure you want to leave? Your changes will be lost.'
|
|
134
|
-
);
|
|
135
|
-
if (!confirmed) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
113
|
+
if (!window.confirm('You have unsaved changes. Leave anyway?')) return;
|
|
138
114
|
}
|
|
139
115
|
window.location.href = '/dashboard/blog';
|
|
140
116
|
}}
|
|
141
|
-
className="
|
|
117
|
+
className="size-9 lg:size-10 flex items-center justify-center bg-dashboard-card border border-dashboard-border rounded-xl text-dashboard-text-secondary hover:text-primary hover:border-primary/30 transition-all active:scale-95 shadow-sm"
|
|
142
118
|
>
|
|
143
|
-
<ArrowLeft size
|
|
119
|
+
<ArrowLeft className="size-[18px] lg:size-[20px]" />
|
|
144
120
|
</button>
|
|
145
|
-
|
|
121
|
+
|
|
122
|
+
<div className="h-6 lg:h-8 w-px bg-dashboard-border/30" />
|
|
123
|
+
|
|
146
124
|
<button
|
|
147
125
|
onClick={onLibraryToggle}
|
|
148
|
-
className={`flex items-center gap-2
|
|
149
|
-
|
|
126
|
+
className={`flex items-center gap-2 lg:gap-3 px-3 lg:px-5 py-2 lg:py-2.5 rounded-xl text-[10px] font-black uppercase tracking-[0.2em] transition-all border ${
|
|
127
|
+
isLibraryOpen
|
|
128
|
+
? 'bg-primary text-white border-primary/20 shadow-lg shadow-primary/20'
|
|
129
|
+
: 'bg-dashboard-card text-dashboard-text-secondary border-dashboard-border hover:border-primary/30'
|
|
130
|
+
}`}
|
|
150
131
|
>
|
|
151
|
-
<Library size={16}
|
|
152
|
-
Library
|
|
132
|
+
<Library size={16} />
|
|
133
|
+
<span className="hidden xl:inline">Blocks Library</span>
|
|
134
|
+
<span className="xl:hidden hidden lg:inline text-[8px]">Blocks</span>
|
|
153
135
|
</button>
|
|
136
|
+
|
|
154
137
|
{/* Language Switcher */}
|
|
155
138
|
{languages.length > 0 && onLanguageChange && (
|
|
156
|
-
|
|
157
|
-
<div className="h-4 w-[1px] bg-neutral-300 dark:border-neutral-700" />
|
|
158
|
-
<div className="relative">
|
|
159
|
-
<button
|
|
160
|
-
onClick={() => setShowLanguageDropdown(!showLanguageDropdown)}
|
|
161
|
-
className="flex items-center gap-2 px-3 py-2 text-[10px] uppercase tracking-widest font-bold bg-dashboard-card border border-dashboard-border rounded-lg text-neutral-600 dark:text-neutral-400 hover:text-dashboard-text hover:border-primary/50 transition-all shadow-sm"
|
|
162
|
-
>
|
|
163
|
-
<Globe size={14} strokeWidth={1.5} />
|
|
164
|
-
<span>{languageLabels[currentLanguage] || currentLanguage.toUpperCase()}</span>
|
|
165
|
-
<ChevronDown size={12} className={`transition-transform ${showLanguageDropdown ? 'rotate-180' : ''}`} />
|
|
166
|
-
</button>
|
|
167
|
-
{showLanguageDropdown && (
|
|
168
|
-
<div className="absolute top-full left-0 mt-2 py-1 bg-dashboard-card border border-dashboard-border rounded-lg shadow-xl z-[9999] min-w-[160px] overflow-hidden">
|
|
169
|
-
<div className="px-3 py-2 text-[9px] text-neutral-500 uppercase tracking-wider border-b border-dashboard-border">
|
|
170
|
-
Beschikbare Talen
|
|
171
|
-
</div>
|
|
172
|
-
{languages.map(lang => (
|
|
173
|
-
<button
|
|
174
|
-
key={lang}
|
|
175
|
-
onClick={() => {
|
|
176
|
-
onLanguageChange(lang);
|
|
177
|
-
setShowLanguageDropdown(false);
|
|
178
|
-
}}
|
|
179
|
-
className={`w-full text-left px-3 py-2 text-[10px] uppercase tracking-wider transition-colors ${lang === currentLanguage
|
|
180
|
-
? 'bg-primary/10 text-primary font-bold'
|
|
181
|
-
: 'text-neutral-600 dark:text-neutral-400 hover:bg-dashboard-bg hover:text-dashboard-text'
|
|
182
|
-
}`}
|
|
183
|
-
>
|
|
184
|
-
{languageLabels[lang] || lang.toUpperCase()}
|
|
185
|
-
</button>
|
|
186
|
-
))}
|
|
187
|
-
{availableToAdd.length > 0 && onAddLanguage && (
|
|
188
|
-
<>
|
|
189
|
-
<div className="my-1 border-t border-dashboard-border" />
|
|
190
|
-
<div className="px-3 py-1 text-[9px] text-neutral-500 uppercase tracking-wider">
|
|
191
|
-
Add Language
|
|
192
|
-
</div>
|
|
193
|
-
{availableToAdd.slice(0, 3).map(lang => (
|
|
194
|
-
<button
|
|
195
|
-
key={lang}
|
|
196
|
-
onClick={() => {
|
|
197
|
-
onAddLanguage(lang);
|
|
198
|
-
setShowLanguageDropdown(false);
|
|
199
|
-
}}
|
|
200
|
-
className="w-full text-left px-3 py-2 text-[10px] uppercase tracking-wider text-neutral-600 dark:text-neutral-400 hover:bg-dashboard-bg hover:text-dashboard-text transition-colors"
|
|
201
|
-
>
|
|
202
|
-
+ {languageLabels[lang] || lang.toUpperCase()}
|
|
203
|
-
</button>
|
|
204
|
-
))}
|
|
205
|
-
</>
|
|
206
|
-
)}
|
|
207
|
-
</div>
|
|
208
|
-
)}
|
|
209
|
-
</div>
|
|
210
|
-
</>
|
|
211
|
-
)}
|
|
212
|
-
</div>
|
|
213
|
-
|
|
214
|
-
<div className="flex items-center gap-4">
|
|
215
|
-
{/* Auto-save Toggle */}
|
|
216
|
-
{onAutoSaveToggle && (
|
|
217
|
-
<div className="flex items-center gap-2">
|
|
139
|
+
<div className="relative group">
|
|
218
140
|
<button
|
|
219
|
-
onClick={() =>
|
|
220
|
-
className=
|
|
221
|
-
? 'bg-primary/20 text-primary border border-primary/30'
|
|
222
|
-
: 'bg-dashboard-bg text-neutral-600 dark:text-neutral-400 border border-dashboard-border hover:text-neutral-950 dark:hover:text-white'
|
|
223
|
-
}`}
|
|
224
|
-
title={autoSaveEnabled ? 'Auto-save enabled (saves after 10s of inactivity)' : 'Click to enable auto-save'}
|
|
141
|
+
onClick={() => setShowLanguageDropdown(!showLanguageDropdown)}
|
|
142
|
+
className="flex items-center gap-2 lg:gap-3 px-3 lg:px-4 py-2 lg:py-2.5 bg-dashboard-card border border-dashboard-border rounded-xl hover:border-primary/30 transition-all shadow-sm"
|
|
225
143
|
>
|
|
226
|
-
<
|
|
227
|
-
<span
|
|
228
|
-
|
|
229
|
-
{autoSaveEnabled ? 'ON' : 'OFF'}
|
|
144
|
+
<img src={getFlagUrl(currentLanguage)} className="w-4 h-2.5 lg:w-5 lg:h-3.5 object-cover rounded-sm border border-white/20" alt="" />
|
|
145
|
+
<span className="text-[10px] font-black uppercase tracking-widest text-dashboard-text-secondary">
|
|
146
|
+
{currentLanguage.toUpperCase()}
|
|
230
147
|
</span>
|
|
231
|
-
{
|
|
232
|
-
{autoSaveEnabled && isDirty && (
|
|
233
|
-
<span className="ml-1.5 text-[9px] font-bold tabular-nums">
|
|
234
|
-
{autoSaveStatus === 'saving' && (
|
|
235
|
-
<span className="text-primary animate-pulse">Saving...</span>
|
|
236
|
-
)}
|
|
237
|
-
{autoSaveStatus === 'saved' && (
|
|
238
|
-
<span className="text-green-500 dark:text-green-400">Saved!</span>
|
|
239
|
-
)}
|
|
240
|
-
{autoSaveStatus === 'error' && (
|
|
241
|
-
<span className="text-red-500 dark:text-red-400">Error</span>
|
|
242
|
-
)}
|
|
243
|
-
{autoSaveStatus === 'idle' && autoSaveCountdown !== null && (
|
|
244
|
-
<span className="text-primary/70">{autoSaveCountdown}s</span>
|
|
245
|
-
)}
|
|
246
|
-
</span>
|
|
247
|
-
)}
|
|
148
|
+
<ChevronDown className={`size-[12px] lg:size-[14px] text-dashboard-text-secondary transition-transform ${showLanguageDropdown ? 'rotate-180' : ''}`} />
|
|
248
149
|
</button>
|
|
249
|
-
|
|
250
|
-
{
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
150
|
+
|
|
151
|
+
{showLanguageDropdown && (
|
|
152
|
+
<div className="absolute top-full left-0 mt-3 p-2 bg-dashboard-bg/95 backdrop-blur-2xl border border-dashboard-border rounded-2xl shadow-2xl z-[100] min-w-[180px] animate-in fade-in zoom-in-95 duration-200">
|
|
153
|
+
<label className="px-3 py-2 text-[8px] font-black text-dashboard-text-secondary uppercase tracking-[0.3em] block border-b border-dashboard-border/30 mb-1">
|
|
154
|
+
Switch Edition
|
|
155
|
+
</label>
|
|
156
|
+
{allCreatedLanguages.map(lang => (
|
|
157
|
+
<button
|
|
158
|
+
key={lang}
|
|
159
|
+
onClick={() => {
|
|
160
|
+
onLanguageChange(lang);
|
|
161
|
+
setShowLanguageDropdown(false);
|
|
162
|
+
}}
|
|
163
|
+
className={`w-full flex items-center gap-3 px-3 py-2.5 rounded-xl transition-all ${
|
|
164
|
+
lang === currentLanguage
|
|
165
|
+
? 'bg-primary/10 text-primary font-bold'
|
|
166
|
+
: 'text-dashboard-text-secondary hover:bg-white/5 hover:text-dashboard-text'
|
|
167
|
+
}`}
|
|
168
|
+
>
|
|
169
|
+
<img src={getFlagUrl(lang)} className="w-4 h-3 object-cover rounded-sm" alt="" />
|
|
170
|
+
<span className="text-[10px] font-black uppercase tracking-widest">{languageLabels[lang] || lang.toUpperCase()}</span>
|
|
171
|
+
</button>
|
|
172
|
+
))}
|
|
173
|
+
|
|
174
|
+
{availableToAdd.length > 0 && onAddLanguage && (
|
|
175
|
+
<>
|
|
176
|
+
<div className="my-2 border-t border-dashboard-border/30 mx-2" />
|
|
177
|
+
<label className="px-3 py-2 text-[8px] font-black text-dashboard-text-secondary uppercase tracking-[0.3em] block mb-1">
|
|
178
|
+
Add Edition
|
|
179
|
+
</label>
|
|
180
|
+
{availableToAdd.map(lang => (
|
|
181
|
+
<button
|
|
182
|
+
key={lang}
|
|
183
|
+
onClick={() => {
|
|
184
|
+
onAddLanguage(lang);
|
|
185
|
+
setShowLanguageDropdown(false);
|
|
186
|
+
}}
|
|
187
|
+
className="w-full flex items-center gap-3 px-3 py-2.5 rounded-xl text-dashboard-text-secondary hover:bg-primary/10 hover:text-primary transition-all group/add"
|
|
188
|
+
>
|
|
189
|
+
<div className="relative">
|
|
190
|
+
<img src={getFlagUrl(lang)} className="w-4 h-3 object-cover rounded-sm opacity-60 group-hover/add:opacity-100 transition-opacity" alt="" />
|
|
191
|
+
<div className="absolute -top-1 -right-1 size-2 bg-primary rounded-full border border-dashboard-bg flex items-center justify-center text-[6px] text-white font-bold">
|
|
192
|
+
+
|
|
193
|
+
</div>
|
|
194
|
+
</div>
|
|
195
|
+
<span className="text-[10px] font-black uppercase tracking-widest">{languageLabels[lang] || lang.toUpperCase()}</span>
|
|
196
|
+
</button>
|
|
197
|
+
))}
|
|
198
|
+
</>
|
|
199
|
+
)}
|
|
200
|
+
</div>
|
|
254
201
|
)}
|
|
255
202
|
</div>
|
|
256
203
|
)}
|
|
257
|
-
|
|
258
|
-
|
|
204
|
+
</div>
|
|
205
|
+
|
|
206
|
+
{/* Middle Section: Status */}
|
|
207
|
+
<div className="hidden md:flex items-center gap-2 lg:gap-4">
|
|
208
|
+
{state.status === 'published' && (
|
|
209
|
+
<div className="flex items-center gap-2 px-3 lg:px-4 py-1.5 bg-emerald-500/10 border border-emerald-500/20 rounded-full text-emerald-500">
|
|
210
|
+
<CheckCircle2 size={12} className="animate-pulse" />
|
|
211
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] hidden lg:inline">Live Edition</span>
|
|
212
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] lg:hidden">Live</span>
|
|
213
|
+
</div>
|
|
214
|
+
)}
|
|
215
|
+
{state.status === 'not-translated' && (
|
|
216
|
+
<div className="flex items-center gap-2 px-3 lg:px-4 py-1.5 bg-blue-500/10 border border-blue-500/20 rounded-full text-blue-500">
|
|
217
|
+
<Plus size={12} />
|
|
218
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] hidden lg:inline">New Edition</span>
|
|
219
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] lg:hidden">New</span>
|
|
220
|
+
</div>
|
|
221
|
+
)}
|
|
222
|
+
{isDirty && !autoSaveEnabled && (
|
|
223
|
+
<div className="flex items-center gap-2 px-3 lg:px-4 py-1.5 bg-amber-500/10 border border-amber-500/20 rounded-full text-amber-500 animate-pulse">
|
|
224
|
+
<Clock size={12} />
|
|
225
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] hidden lg:inline">Unsaved Edits</span>
|
|
226
|
+
<span className="text-[9px] font-black uppercase tracking-[0.2em] lg:hidden">Dirty</span>
|
|
227
|
+
</div>
|
|
228
|
+
)}
|
|
229
|
+
</div>
|
|
230
|
+
|
|
231
|
+
{/* Right Section: Controls & Save */}
|
|
232
|
+
<div className="flex items-center gap-2 lg:gap-4">
|
|
233
|
+
{/* Auto-save */}
|
|
234
|
+
{onAutoSaveToggle && (
|
|
259
235
|
<button
|
|
260
|
-
onClick={() =>
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
? 'bg-primary text-white shadow-sm'
|
|
267
|
-
: 'text-neutral-600 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'
|
|
268
|
-
}`}
|
|
269
|
-
title="Edit mode - Make changes to your post"
|
|
236
|
+
onClick={() => onAutoSaveToggle(!autoSaveEnabled)}
|
|
237
|
+
className={`group flex items-center gap-2 lg:gap-3 px-3 lg:px-4 py-2 lg:py-2.5 rounded-xl border transition-all ${
|
|
238
|
+
autoSaveEnabled
|
|
239
|
+
? 'bg-primary/10 border-primary/30 text-primary'
|
|
240
|
+
: 'bg-dashboard-card border border-dashboard-border text-dashboard-text-secondary'
|
|
241
|
+
}`}
|
|
270
242
|
>
|
|
271
|
-
<
|
|
272
|
-
<span>
|
|
243
|
+
<Clock size={14} className={autoSaveEnabled && autoSaveStatus === 'saving' ? 'animate-spin' : ''} />
|
|
244
|
+
<span className="text-[9px] font-black uppercase tracking-widest hidden lg:inline">
|
|
245
|
+
{autoSaveStatus === 'saving' ? 'Syncing...' : 'Auto-Sync'}
|
|
246
|
+
</span>
|
|
247
|
+
<div className={`size-1.5 rounded-full ${autoSaveEnabled ? 'bg-primary animate-pulse' : 'bg-dashboard-text-secondary/30'}`} />
|
|
248
|
+
</button>
|
|
249
|
+
)}
|
|
250
|
+
|
|
251
|
+
{/* Edit/Preview Toggle */}
|
|
252
|
+
<div className="flex items-center bg-dashboard-card border border-dashboard-border rounded-xl p-1 shadow-inner">
|
|
253
|
+
<button
|
|
254
|
+
onClick={() => isPreviewMode && onPreviewToggle()}
|
|
255
|
+
className={`flex items-center gap-2 px-3 lg:px-4 py-1.5 lg:py-2 rounded-lg text-[10px] font-black uppercase tracking-widest transition-all ${
|
|
256
|
+
!isPreviewMode ? 'bg-primary text-white shadow-md' : 'text-dashboard-text-secondary hover:text-dashboard-text'
|
|
257
|
+
}`}
|
|
258
|
+
>
|
|
259
|
+
<Edit size={12} />
|
|
260
|
+
<span className="hidden sm:inline">Edit</span>
|
|
273
261
|
</button>
|
|
274
262
|
<button
|
|
275
|
-
onClick={() =>
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}}
|
|
280
|
-
className={`flex items-center gap-1.5 px-3 py-1.5 rounded-full text-[10px] uppercase tracking-widest font-bold transition-all ${isPreviewMode
|
|
281
|
-
? 'bg-primary text-white shadow-sm'
|
|
282
|
-
: 'text-neutral-600 dark:text-neutral-400 hover:text-neutral-950 dark:hover:text-white'
|
|
283
|
-
}`}
|
|
284
|
-
title="Preview mode - See how your post will look"
|
|
263
|
+
onClick={() => !isPreviewMode && onPreviewToggle()}
|
|
264
|
+
className={`flex items-center gap-2 px-3 lg:px-4 py-1.5 lg:py-2 rounded-lg text-[10px] font-black uppercase tracking-widest transition-all ${
|
|
265
|
+
isPreviewMode ? 'bg-primary text-white shadow-md' : 'text-dashboard-text-secondary hover:text-dashboard-text'
|
|
266
|
+
}`}
|
|
285
267
|
>
|
|
286
|
-
<Eye size={12}
|
|
287
|
-
<span>
|
|
268
|
+
<Eye size={12} />
|
|
269
|
+
<span className="hidden sm:inline">View</span>
|
|
288
270
|
</button>
|
|
289
271
|
</div>
|
|
290
|
-
|
|
291
|
-
{
|
|
272
|
+
|
|
273
|
+
{/* Save Options */}
|
|
274
|
+
<div className="flex items-center gap-2">
|
|
275
|
+
{state.status !== 'published' && (
|
|
276
|
+
<button
|
|
277
|
+
onClick={handleSaveDraftClick}
|
|
278
|
+
disabled={isSaving}
|
|
279
|
+
className="px-4 lg:px-6 py-2 lg:py-2.5 bg-dashboard-card border border-dashboard-border text-dashboard-text-secondary rounded-xl text-[10px] font-black uppercase tracking-[0.2em] hover:border-primary/30 transition-all active:scale-95"
|
|
280
|
+
>
|
|
281
|
+
<span className="hidden lg:inline">{isSaving ? '...' : 'Save Draft'}</span>
|
|
282
|
+
<span className="lg:hidden">{isSaving ? '...' : 'Draft'}</span>
|
|
283
|
+
</button>
|
|
284
|
+
)}
|
|
292
285
|
<button
|
|
293
|
-
onClick={
|
|
286
|
+
onClick={handlePublishClick}
|
|
294
287
|
disabled={isSaving}
|
|
295
|
-
className=
|
|
296
|
-
? 'opacity-50 cursor-not-allowed'
|
|
297
|
-
: 'hover:bg-dashboard-bg'
|
|
298
|
-
}`}
|
|
288
|
+
className="px-5 lg:px-8 py-2 lg:py-2.5 bg-primary text-white rounded-xl text-[10px] font-black uppercase tracking-[0.3em] shadow-xl shadow-primary/20 hover:scale-[1.02] active:scale-95 transition-all"
|
|
299
289
|
>
|
|
300
|
-
{isSaving ? '
|
|
290
|
+
<span className="hidden lg:inline">{isSaving ? 'Publishing...' : state.status === 'published' ? 'Update Live' : 'Go Live'}</span>
|
|
291
|
+
<Save size={14} className="lg:hidden" />
|
|
301
292
|
</button>
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
<button
|
|
305
|
-
onClick={handlePublishClick}
|
|
306
|
-
disabled={isSaving}
|
|
307
|
-
className={`px-6 py-2 bg-primary text-white rounded-full text-[10px] font-bold uppercase tracking-widest transition-all shadow-lg shadow-primary/20 ${isSaving
|
|
308
|
-
? 'opacity-50 cursor-not-allowed'
|
|
309
|
-
: 'hover:bg-primary/90'
|
|
310
|
-
}`}
|
|
311
|
-
>
|
|
312
|
-
{isSaving ? 'Saving...' : state.status === 'published' ? 'Update Post' : 'Publish Post'}
|
|
313
|
-
</button>
|
|
293
|
+
</div>
|
|
294
|
+
|
|
314
295
|
<button
|
|
315
296
|
onClick={onSidebarToggle}
|
|
316
|
-
className={`
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
297
|
+
className={`size-9 lg:size-10 flex items-center justify-center rounded-xl transition-all border ${
|
|
298
|
+
isSidebarOpen
|
|
299
|
+
? 'bg-primary/10 border-primary/30 text-primary shadow-lg shadow-primary/10'
|
|
300
|
+
: 'bg-dashboard-card border border-dashboard-border text-dashboard-text-secondary hover:border-primary/30'
|
|
301
|
+
}`}
|
|
320
302
|
>
|
|
321
|
-
<Settings2 size
|
|
303
|
+
<Settings2 className="size-[18px] lg:size-[20px]" />
|
|
322
304
|
</button>
|
|
323
305
|
</div>
|
|
324
306
|
|
|
325
|
-
{/* Save Confirmation Modal */}
|
|
326
307
|
<SaveConfirmationModal
|
|
327
308
|
isOpen={showConfirmModal}
|
|
328
309
|
onClose={() => {
|
|
@@ -340,4 +321,3 @@ export function EditorHeader({
|
|
|
340
321
|
</div>
|
|
341
322
|
);
|
|
342
323
|
}
|
|
343
|
-
|