@actuate-media/cms-admin 0.8.0 → 0.8.2
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/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +44 -42
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/lib/search.test.js +10 -10
- package/dist/__tests__/lib/search.test.js.map +1 -1
- package/dist/__tests__/lib/utils.test.js.map +1 -1
- package/dist/__tests__/router/match-route.test.js.map +1 -1
- package/dist/__tests__/router/strip-base.test.js.map +1 -1
- package/dist/actuate-admin.css +1 -1
- package/dist/components/Breadcrumbs.d.ts.map +1 -1
- package/dist/components/Breadcrumbs.js +2 -4
- package/dist/components/Breadcrumbs.js.map +1 -1
- package/dist/components/CommandPalette.d.ts.map +1 -1
- package/dist/components/CommandPalette.js +7 -3
- package/dist/components/CommandPalette.js.map +1 -1
- package/dist/components/ContentOverviewChart.d.ts.map +1 -1
- package/dist/components/ContentOverviewChart.js.map +1 -1
- package/dist/components/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/ErrorBoundary.js.map +1 -1
- package/dist/components/FocalPointPicker.d.ts.map +1 -1
- package/dist/components/FocalPointPicker.js +4 -2
- package/dist/components/FocalPointPicker.js.map +1 -1
- package/dist/components/FolderTree.d.ts.map +1 -1
- package/dist/components/FolderTree.js +18 -10
- package/dist/components/FolderTree.js.map +1 -1
- package/dist/components/LivePreview.d.ts +1 -1
- package/dist/components/LivePreview.d.ts.map +1 -1
- package/dist/components/LivePreview.js +6 -2
- package/dist/components/LivePreview.js.map +1 -1
- package/dist/components/LocaleProvider.d.ts.map +1 -1
- package/dist/components/LocaleProvider.js.map +1 -1
- package/dist/components/LocaleSwitcher.d.ts.map +1 -1
- package/dist/components/LocaleSwitcher.js +1 -1
- package/dist/components/LocaleSwitcher.js.map +1 -1
- package/dist/components/MediaPickerModal.d.ts.map +1 -1
- package/dist/components/MediaPickerModal.js.map +1 -1
- package/dist/components/PresenceIndicator.d.ts.map +1 -1
- package/dist/components/PresenceIndicator.js +5 -2
- package/dist/components/PresenceIndicator.js.map +1 -1
- package/dist/components/SEOPanel.d.ts +1 -1
- package/dist/components/SEOPanel.d.ts.map +1 -1
- package/dist/components/SEOPanel.js +110 -24
- package/dist/components/SEOPanel.js.map +1 -1
- package/dist/components/SEOPerformance.d.ts.map +1 -1
- package/dist/components/SEOPerformance.js +2 -2
- package/dist/components/SEOPerformance.js.map +1 -1
- package/dist/components/ThemeProvider.d.ts.map +1 -1
- package/dist/components/ThemeProvider.js.map +1 -1
- package/dist/components/TipTapEditor.d.ts.map +1 -1
- package/dist/components/TipTapEditor.js +5 -1
- package/dist/components/TipTapEditor.js.map +1 -1
- package/dist/components/VersionHistory.d.ts +1 -1
- package/dist/components/VersionHistory.d.ts.map +1 -1
- package/dist/components/VersionHistory.js +1 -1
- package/dist/components/VersionHistory.js.map +1 -1
- package/dist/components/ui/Avatar.d.ts.map +1 -1
- package/dist/components/ui/Avatar.js.map +1 -1
- package/dist/components/ui/Badge.d.ts.map +1 -1
- package/dist/components/ui/Badge.js.map +1 -1
- package/dist/components/ui/Button.d.ts.map +1 -1
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/CommandPalette.d.ts.map +1 -1
- package/dist/components/ui/CommandPalette.js +8 -2
- package/dist/components/ui/CommandPalette.js.map +1 -1
- package/dist/components/ui/ConfirmDialog.d.ts.map +1 -1
- package/dist/components/ui/ConfirmDialog.js.map +1 -1
- package/dist/components/ui/DataTable.d.ts.map +1 -1
- package/dist/components/ui/DataTable.js +1 -3
- package/dist/components/ui/DataTable.js.map +1 -1
- package/dist/components/ui/EmptyState.d.ts.map +1 -1
- package/dist/components/ui/EmptyState.js +1 -1
- package/dist/components/ui/EmptyState.js.map +1 -1
- package/dist/components/ui/Modal.d.ts.map +1 -1
- package/dist/components/ui/Modal.js.map +1 -1
- package/dist/components/ui/Pagination.d.ts +1 -1
- package/dist/components/ui/Pagination.d.ts.map +1 -1
- package/dist/components/ui/Pagination.js +7 -2
- package/dist/components/ui/Pagination.js.map +1 -1
- package/dist/components/ui/SearchInput.d.ts.map +1 -1
- package/dist/components/ui/SearchInput.js.map +1 -1
- package/dist/components/ui/Skeleton.d.ts.map +1 -1
- package/dist/components/ui/Skeleton.js.map +1 -1
- package/dist/components/ui/Toast.d.ts.map +1 -1
- package/dist/components/ui/Toast.js.map +1 -1
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js.map +1 -1
- package/dist/fields/ArrayField.d.ts.map +1 -1
- package/dist/fields/ArrayField.js +1 -1
- package/dist/fields/ArrayField.js.map +1 -1
- package/dist/fields/BlockBuilderField.d.ts.map +1 -1
- package/dist/fields/BlockBuilderField.js +7 -7
- package/dist/fields/BlockBuilderField.js.map +1 -1
- package/dist/fields/DateField.d.ts.map +1 -1
- package/dist/fields/DateField.js +1 -1
- package/dist/fields/DateField.js.map +1 -1
- package/dist/fields/FieldRenderer.d.ts.map +1 -1
- package/dist/fields/FieldRenderer.js.map +1 -1
- package/dist/fields/GroupField.d.ts.map +1 -1
- package/dist/fields/GroupField.js +1 -1
- package/dist/fields/GroupField.js.map +1 -1
- package/dist/fields/MediaField.d.ts.map +1 -1
- package/dist/fields/MediaField.js +1 -1
- package/dist/fields/MediaField.js.map +1 -1
- package/dist/fields/NavBuilderField.d.ts.map +1 -1
- package/dist/fields/NavBuilderField.js +2 -5
- package/dist/fields/NavBuilderField.js.map +1 -1
- package/dist/fields/NumberField.d.ts +1 -1
- package/dist/fields/NumberField.d.ts.map +1 -1
- package/dist/fields/NumberField.js +2 -2
- package/dist/fields/NumberField.js.map +1 -1
- package/dist/fields/RelationshipField.d.ts.map +1 -1
- package/dist/fields/RelationshipField.js +7 -3
- package/dist/fields/RelationshipField.js.map +1 -1
- package/dist/fields/RichTextField.d.ts +1 -1
- package/dist/fields/RichTextField.d.ts.map +1 -1
- package/dist/fields/RichTextField.js +2 -2
- package/dist/fields/RichTextField.js.map +1 -1
- package/dist/fields/SelectField.d.ts.map +1 -1
- package/dist/fields/SelectField.js +9 -7
- package/dist/fields/SelectField.js.map +1 -1
- package/dist/fields/SlugField.d.ts.map +1 -1
- package/dist/fields/SlugField.js +1 -1
- package/dist/fields/SlugField.js.map +1 -1
- package/dist/fields/TextField.d.ts +1 -1
- package/dist/fields/TextField.d.ts.map +1 -1
- package/dist/fields/TextField.js +2 -2
- package/dist/fields/TextField.js.map +1 -1
- package/dist/fields/ToggleField.d.ts.map +1 -1
- package/dist/fields/ToggleField.js +1 -1
- package/dist/fields/ToggleField.js.map +1 -1
- package/dist/fields/block-types.d.ts.map +1 -1
- package/dist/fields/block-types.js +28 -8
- package/dist/fields/block-types.js.map +1 -1
- package/dist/fields/index.d.ts.map +1 -1
- package/dist/fields/index.js.map +1 -1
- package/dist/hooks/useBuilderState.d.ts.map +1 -1
- package/dist/hooks/useBuilderState.js.map +1 -1
- package/dist/hooks/useContentLock.d.ts.map +1 -1
- package/dist/hooks/useContentLock.js.map +1 -1
- package/dist/hooks/useDebounce.js.map +1 -1
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -1
- package/dist/hooks/useKeyboardShortcuts.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/Header.d.ts.map +1 -1
- package/dist/layout/Header.js.map +1 -1
- package/dist/layout/Layout.d.ts.map +1 -1
- package/dist/layout/Layout.js.map +1 -1
- package/dist/layout/Sidebar.d.ts +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +5 -8
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/lib/search.js +3 -5
- package/dist/lib/search.js.map +1 -1
- package/dist/lib/useApiData.d.ts.map +1 -1
- package/dist/lib/useApiData.js.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +1 -3
- package/dist/router/index.js.map +1 -1
- package/dist/views/CollectionList.d.ts.map +1 -1
- package/dist/views/CollectionList.js +56 -17
- package/dist/views/CollectionList.js.map +1 -1
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +26 -13
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/DocumentEdit.d.ts +1 -1
- package/dist/views/DocumentEdit.d.ts.map +1 -1
- package/dist/views/DocumentEdit.js +33 -15
- package/dist/views/DocumentEdit.js.map +1 -1
- package/dist/views/ForgotPassword.d.ts.map +1 -1
- package/dist/views/ForgotPassword.js.map +1 -1
- package/dist/views/FormEditor.d.ts.map +1 -1
- package/dist/views/FormEditor.js +8 -2
- package/dist/views/FormEditor.js.map +1 -1
- package/dist/views/FormSubmissions.d.ts.map +1 -1
- package/dist/views/FormSubmissions.js +6 -6
- package/dist/views/FormSubmissions.js.map +1 -1
- package/dist/views/Forms.d.ts.map +1 -1
- package/dist/views/Forms.js.map +1 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/Login.js +5 -2
- package/dist/views/Login.js.map +1 -1
- package/dist/views/MediaBrowser.d.ts.map +1 -1
- package/dist/views/MediaBrowser.js +39 -19
- package/dist/views/MediaBrowser.js.map +1 -1
- package/dist/views/PageEditor.d.ts.map +1 -1
- package/dist/views/PageEditor.js.map +1 -1
- package/dist/views/Pages.d.ts.map +1 -1
- package/dist/views/Pages.js +20 -10
- package/dist/views/Pages.js.map +1 -1
- package/dist/views/PostEditor.d.ts.map +1 -1
- package/dist/views/PostEditor.js.map +1 -1
- package/dist/views/Posts.d.ts.map +1 -1
- package/dist/views/Posts.js +13 -7
- package/dist/views/Posts.js.map +1 -1
- package/dist/views/Redirects.d.ts.map +1 -1
- package/dist/views/Redirects.js +17 -5
- package/dist/views/Redirects.js.map +1 -1
- package/dist/views/ResetPassword.d.ts.map +1 -1
- package/dist/views/ResetPassword.js.map +1 -1
- package/dist/views/SEO.d.ts.map +1 -1
- package/dist/views/SEO.js +40 -17
- package/dist/views/SEO.js.map +1 -1
- package/dist/views/ScriptTagEditor.d.ts.map +1 -1
- package/dist/views/ScriptTagEditor.js +2 -1
- package/dist/views/ScriptTagEditor.js.map +1 -1
- package/dist/views/ScriptTags.d.ts.map +1 -1
- package/dist/views/ScriptTags.js.map +1 -1
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +38 -11
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/SetupWizard.d.ts.map +1 -1
- package/dist/views/SetupWizard.js.map +1 -1
- package/dist/views/Users.d.ts.map +1 -1
- package/dist/views/Users.js +5 -3
- package/dist/views/Users.js.map +1 -1
- package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -1
- package/dist/views/page-builder/AIBlockAssist.js +1 -1
- package/dist/views/page-builder/AIBlockAssist.js.map +1 -1
- package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -1
- package/dist/views/page-builder/AIGenerateDialog.js +4 -1
- package/dist/views/page-builder/AIGenerateDialog.js.map +1 -1
- package/dist/views/page-builder/BlockEditor.d.ts.map +1 -1
- package/dist/views/page-builder/BlockEditor.js +1 -1
- package/dist/views/page-builder/BlockEditor.js.map +1 -1
- package/dist/views/page-builder/BlockPicker.d.ts.map +1 -1
- package/dist/views/page-builder/BlockPicker.js.map +1 -1
- package/dist/views/page-builder/BottomBar.d.ts.map +1 -1
- package/dist/views/page-builder/BottomBar.js.map +1 -1
- package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -1
- package/dist/views/page-builder/BuilderToolbar.js.map +1 -1
- package/dist/views/page-builder/ContextPanel.d.ts.map +1 -1
- package/dist/views/page-builder/ContextPanel.js +4 -1
- package/dist/views/page-builder/ContextPanel.js.map +1 -1
- package/dist/views/page-builder/DesignScore.d.ts.map +1 -1
- package/dist/views/page-builder/DesignScore.js.map +1 -1
- package/dist/views/page-builder/NodeSettings.d.ts.map +1 -1
- package/dist/views/page-builder/NodeSettings.js +1 -1
- package/dist/views/page-builder/NodeSettings.js.map +1 -1
- package/dist/views/page-builder/PageBuilder.d.ts +1 -1
- package/dist/views/page-builder/PageBuilder.d.ts.map +1 -1
- package/dist/views/page-builder/PageBuilder.js +4 -2
- package/dist/views/page-builder/PageBuilder.js.map +1 -1
- package/dist/views/page-builder/PageSettings.d.ts.map +1 -1
- package/dist/views/page-builder/PageSettings.js.map +1 -1
- package/dist/views/page-builder/PageTemplates.d.ts.map +1 -1
- package/dist/views/page-builder/PageTemplates.js.map +1 -1
- package/dist/views/page-builder/SEOPanel.d.ts.map +1 -1
- package/dist/views/page-builder/SEOPanel.js +1 -3
- package/dist/views/page-builder/SEOPanel.js.map +1 -1
- package/dist/views/page-builder/SavedSections.d.ts.map +1 -1
- package/dist/views/page-builder/SavedSections.js +3 -7
- package/dist/views/page-builder/SavedSections.js.map +1 -1
- package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -1
- package/dist/views/page-builder/TemplatePicker.js.map +1 -1
- package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/CTAPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/CodePreview.js +1 -5
- package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/FAQPreview.js +4 -1
- package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/FormPreview.js +2 -2
- package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/GalleryPreview.js +1 -3
- package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/TextPreview.js +2 -6
- package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/VideoPreview.js +2 -5
- package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -1
- package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -1
- package/dist/views/page-builder/block-renderers/index.js.map +1 -1
- package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/BlockRenderer.js +1 -5
- package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -1
- package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -1
- package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/ColumnRenderer.js +1 -5
- package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -1
- package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/ContainerRenderer.js +1 -5
- package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -1
- package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/RowRenderer.js +1 -5
- package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -1
- package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/SectionRenderer.js +1 -5
- package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -1
- package/dist/views/page-builder/canvas/index.d.ts.map +1 -1
- package/dist/views/page-builder/canvas/index.js.map +1 -1
- package/package.json +2 -2
- package/src/AdminRoot.tsx +263 -191
- package/src/__tests__/lib/search.test.ts +60 -69
- package/src/__tests__/lib/utils.test.ts +12 -12
- package/src/__tests__/router/match-route.test.ts +24 -26
- package/src/__tests__/router/strip-base.test.ts +15 -15
- package/src/components/Breadcrumbs.tsx +27 -24
- package/src/components/CommandPalette.tsx +115 -99
- package/src/components/ContentOverviewChart.tsx +19 -14
- package/src/components/ErrorBoundary.tsx +13 -13
- package/src/components/FocalPointPicker.tsx +31 -20
- package/src/components/FolderTree.tsx +172 -139
- package/src/components/LivePreview.tsx +68 -41
- package/src/components/LocaleProvider.tsx +26 -20
- package/src/components/LocaleSwitcher.tsx +9 -11
- package/src/components/MediaPickerModal.tsx +46 -45
- package/src/components/PresenceIndicator.tsx +30 -27
- package/src/components/SEOPanel.tsx +378 -228
- package/src/components/SEOPerformance.tsx +52 -30
- package/src/components/ThemeProvider.tsx +46 -46
- package/src/components/TipTapEditor.tsx +60 -64
- package/src/components/VersionHistory.tsx +63 -52
- package/src/components/ui/Avatar.tsx +8 -8
- package/src/components/ui/Badge.tsx +7 -5
- package/src/components/ui/Button.tsx +24 -13
- package/src/components/ui/CommandPalette.tsx +56 -42
- package/src/components/ui/ConfirmDialog.tsx +14 -14
- package/src/components/ui/DataTable.tsx +37 -39
- package/src/components/ui/EmptyState.tsx +9 -11
- package/src/components/ui/Modal.tsx +21 -15
- package/src/components/ui/Pagination.tsx +34 -19
- package/src/components/ui/SearchInput.tsx +17 -7
- package/src/components/ui/Skeleton.tsx +7 -7
- package/src/components/ui/Toast.tsx +29 -22
- package/src/components/ui/index.ts +24 -24
- package/src/fields/ArrayField.tsx +43 -25
- package/src/fields/BlockBuilderField.tsx +80 -99
- package/src/fields/DateField.tsx +20 -12
- package/src/fields/FieldRenderer.tsx +34 -34
- package/src/fields/GroupField.tsx +8 -10
- package/src/fields/MediaField.tsx +8 -10
- package/src/fields/NavBuilderField.tsx +24 -25
- package/src/fields/NumberField.tsx +21 -14
- package/src/fields/RelationshipField.tsx +105 -91
- package/src/fields/RichTextField.tsx +16 -12
- package/src/fields/SelectField.tsx +42 -34
- package/src/fields/SlugField.tsx +29 -17
- package/src/fields/TextField.tsx +24 -16
- package/src/fields/ToggleField.tsx +7 -9
- package/src/fields/block-types.ts +50 -24
- package/src/fields/index.ts +17 -17
- package/src/hooks/useBuilderState.ts +260 -221
- package/src/hooks/useContentLock.ts +23 -20
- package/src/hooks/useDebounce.ts +7 -7
- package/src/hooks/useKeyboardShortcuts.ts +16 -16
- package/src/index.ts +69 -58
- package/src/layout/Header.tsx +21 -20
- package/src/layout/Layout.tsx +22 -24
- package/src/layout/Sidebar.tsx +107 -72
- package/src/lib/api.ts +34 -34
- package/src/lib/search.ts +30 -34
- package/src/lib/useApiData.ts +65 -62
- package/src/lib/utils.ts +3 -3
- package/src/router/index.ts +33 -35
- package/src/styles/build-input.css +2 -2
- package/src/styles/tailwind.css +1 -1
- package/src/styles/theme.css +26 -2
- package/src/views/CollectionList.tsx +275 -121
- package/src/views/Dashboard.tsx +164 -117
- package/src/views/DocumentEdit.tsx +298 -253
- package/src/views/ForgotPassword.tsx +27 -23
- package/src/views/FormEditor.tsx +165 -99
- package/src/views/FormSubmissions.tsx +261 -117
- package/src/views/Forms.tsx +56 -26
- package/src/views/Login.tsx +107 -84
- package/src/views/MediaBrowser.tsx +717 -523
- package/src/views/PageEditor.tsx +44 -46
- package/src/views/Pages.tsx +312 -149
- package/src/views/PostEditor.tsx +57 -51
- package/src/views/Posts.tsx +206 -74
- package/src/views/Redirects.tsx +173 -117
- package/src/views/ResetPassword.tsx +43 -32
- package/src/views/SEO.tsx +607 -160
- package/src/views/ScriptTagEditor.tsx +69 -69
- package/src/views/ScriptTags.tsx +54 -42
- package/src/views/Settings.tsx +430 -220
- package/src/views/SetupWizard.tsx +69 -46
- package/src/views/Users.tsx +154 -120
- package/src/views/page-builder/AIBlockAssist.tsx +21 -25
- package/src/views/page-builder/AIGenerateDialog.tsx +134 -127
- package/src/views/page-builder/BlockEditor.tsx +94 -96
- package/src/views/page-builder/BlockPicker.tsx +73 -88
- package/src/views/page-builder/BottomBar.tsx +15 -11
- package/src/views/page-builder/BuilderToolbar.tsx +32 -29
- package/src/views/page-builder/ContextPanel.tsx +57 -57
- package/src/views/page-builder/DesignScore.tsx +52 -59
- package/src/views/page-builder/NodeSettings.tsx +59 -59
- package/src/views/page-builder/PageBuilder.tsx +156 -155
- package/src/views/page-builder/PageSettings.tsx +16 -15
- package/src/views/page-builder/PageTemplates.tsx +23 -17
- package/src/views/page-builder/SEOPanel.tsx +90 -111
- package/src/views/page-builder/SavedSections.tsx +99 -105
- package/src/views/page-builder/TemplatePicker.tsx +44 -48
- package/src/views/page-builder/block-renderers/CTAPreview.tsx +11 -13
- package/src/views/page-builder/block-renderers/CardsPreview.tsx +13 -15
- package/src/views/page-builder/block-renderers/CodePreview.tsx +16 -16
- package/src/views/page-builder/block-renderers/FAQPreview.tsx +20 -23
- package/src/views/page-builder/block-renderers/FallbackPreview.tsx +5 -5
- package/src/views/page-builder/block-renderers/FormPreview.tsx +9 -13
- package/src/views/page-builder/block-renderers/GalleryPreview.tsx +22 -28
- package/src/views/page-builder/block-renderers/HeroPreview.tsx +17 -30
- package/src/views/page-builder/block-renderers/ImagePreview.tsx +12 -12
- package/src/views/page-builder/block-renderers/TextPreview.tsx +22 -22
- package/src/views/page-builder/block-renderers/VideoPreview.tsx +13 -18
- package/src/views/page-builder/block-renderers/index.ts +17 -17
- package/src/views/page-builder/canvas/BlockRenderer.tsx +19 -23
- package/src/views/page-builder/canvas/BuilderCanvas.tsx +17 -20
- package/src/views/page-builder/canvas/ColumnRenderer.tsx +22 -26
- package/src/views/page-builder/canvas/ContainerRenderer.tsx +20 -24
- package/src/views/page-builder/canvas/RowRenderer.tsx +19 -23
- package/src/views/page-builder/canvas/SectionRenderer.tsx +30 -34
- package/src/views/page-builder/canvas/index.ts +2 -2
|
@@ -1,45 +1,56 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import {
|
|
4
|
+
Search,
|
|
5
|
+
AlertTriangle,
|
|
6
|
+
FileWarning,
|
|
7
|
+
ImageOff,
|
|
8
|
+
LinkIcon,
|
|
9
|
+
ChevronLeft,
|
|
10
|
+
ChevronRight,
|
|
11
|
+
} from 'lucide-react'
|
|
12
|
+
import { useState } from 'react'
|
|
13
|
+
import { useApiData } from '../lib/useApiData.js'
|
|
6
14
|
|
|
7
15
|
interface SEOSummary {
|
|
8
|
-
totalPages: number
|
|
16
|
+
totalPages: number
|
|
9
17
|
issuesSummary: {
|
|
10
|
-
missingMetaDescriptions: number
|
|
11
|
-
brokenInternalLinks: number
|
|
12
|
-
missingAltText: number
|
|
13
|
-
}
|
|
14
|
-
topContent: { id: string; title: string; collection: string; score: number }[]
|
|
18
|
+
missingMetaDescriptions: number
|
|
19
|
+
brokenInternalLinks: number
|
|
20
|
+
missingAltText: number
|
|
21
|
+
}
|
|
22
|
+
topContent: { id: string; title: string; collection: string; score: number }[]
|
|
15
23
|
}
|
|
16
24
|
|
|
17
25
|
function ScoreBadge({ score }: { score: number }) {
|
|
18
|
-
const color = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-amber-500' : 'text-red-500'
|
|
19
|
-
const bg = score >= 80 ? 'bg-green-50' : score >= 60 ? 'bg-amber-50' : 'bg-red-50'
|
|
26
|
+
const color = score >= 80 ? 'text-green-600' : score >= 60 ? 'text-amber-500' : 'text-red-500'
|
|
27
|
+
const bg = score >= 80 ? 'bg-green-50' : score >= 60 ? 'bg-amber-50' : 'bg-red-50'
|
|
20
28
|
return (
|
|
21
|
-
<span
|
|
29
|
+
<span
|
|
30
|
+
className={`inline-flex items-center justify-center w-9 h-9 rounded-full text-sm font-semibold ${color} ${bg}`}
|
|
31
|
+
>
|
|
22
32
|
{score}
|
|
23
33
|
</span>
|
|
24
|
-
)
|
|
34
|
+
)
|
|
25
35
|
}
|
|
26
36
|
|
|
27
37
|
export interface SEOPerformanceProps {
|
|
28
|
-
onNavigate?: (path: string) => void
|
|
38
|
+
onNavigate?: (path: string) => void
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
32
|
-
const { data, loading, error } = useApiData<SEOSummary>('/seo/summary')
|
|
33
|
-
const [page, setPage] = useState(0)
|
|
34
|
-
const perPage = 5
|
|
42
|
+
const { data, loading, error } = useApiData<SEOSummary>('/seo/summary')
|
|
43
|
+
const [page, setPage] = useState(0)
|
|
44
|
+
const perPage = 5
|
|
35
45
|
|
|
36
|
-
if (loading || error || !data) return null
|
|
46
|
+
if (loading || error || !data) return null
|
|
37
47
|
|
|
38
|
-
const issues = data.issuesSummary
|
|
39
|
-
const totalIssues =
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
const
|
|
48
|
+
const issues = data.issuesSummary
|
|
49
|
+
const totalIssues =
|
|
50
|
+
issues.missingMetaDescriptions + issues.brokenInternalLinks + issues.missingAltText
|
|
51
|
+
const topContent = data.topContent ?? []
|
|
52
|
+
const totalPages = Math.max(1, Math.ceil(topContent.length / perPage))
|
|
53
|
+
const visible = topContent.slice(page * perPage, (page + 1) * perPage)
|
|
43
54
|
|
|
44
55
|
return (
|
|
45
56
|
<div className="bg-white rounded-lg border border-gray-200">
|
|
@@ -49,7 +60,9 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
49
60
|
<h2 className="text-sm font-semibold text-gray-900">SEO Performance</h2>
|
|
50
61
|
</div>
|
|
51
62
|
{totalIssues > 0 && (
|
|
52
|
-
<span className="text-xs text-gray-500">
|
|
63
|
+
<span className="text-xs text-gray-500">
|
|
64
|
+
{totalIssues} issue{totalIssues !== 1 ? 's' : ''} found
|
|
65
|
+
</span>
|
|
53
66
|
)}
|
|
54
67
|
</div>
|
|
55
68
|
|
|
@@ -72,7 +85,10 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
72
85
|
</div>
|
|
73
86
|
{topContent.length > perPage && (
|
|
74
87
|
<div className="flex items-center justify-between mt-3 pt-3 border-t border-gray-100 text-xs text-gray-500">
|
|
75
|
-
<span>
|
|
88
|
+
<span>
|
|
89
|
+
Showing {page * perPage + 1}-{Math.min((page + 1) * perPage, topContent.length)} of{' '}
|
|
90
|
+
{topContent.length}
|
|
91
|
+
</span>
|
|
76
92
|
<div className="flex items-center gap-1">
|
|
77
93
|
<button
|
|
78
94
|
onClick={() => setPage(Math.max(0, page - 1))}
|
|
@@ -81,7 +97,9 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
81
97
|
>
|
|
82
98
|
<ChevronLeft className="w-3.5 h-3.5" />
|
|
83
99
|
</button>
|
|
84
|
-
<span>
|
|
100
|
+
<span>
|
|
101
|
+
Page {page + 1} of {totalPages}
|
|
102
|
+
</span>
|
|
85
103
|
<button
|
|
86
104
|
onClick={() => setPage(Math.min(totalPages - 1, page + 1))}
|
|
87
105
|
disabled={page >= totalPages - 1}
|
|
@@ -102,14 +120,18 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
102
120
|
<FileWarning className="w-4 h-4 text-red-400" />
|
|
103
121
|
<span className="text-sm text-gray-700">Missing meta descriptions</span>
|
|
104
122
|
</div>
|
|
105
|
-
<span className="text-sm font-semibold text-gray-900">
|
|
123
|
+
<span className="text-sm font-semibold text-gray-900">
|
|
124
|
+
{issues.missingMetaDescriptions}
|
|
125
|
+
</span>
|
|
106
126
|
</div>
|
|
107
127
|
<div className="flex items-center justify-between">
|
|
108
128
|
<div className="flex items-center gap-2">
|
|
109
129
|
<LinkIcon className="w-4 h-4 text-red-400" />
|
|
110
130
|
<span className="text-sm text-gray-700">Broken internal links</span>
|
|
111
131
|
</div>
|
|
112
|
-
<span className="text-sm font-semibold text-gray-900">
|
|
132
|
+
<span className="text-sm font-semibold text-gray-900">
|
|
133
|
+
{issues.brokenInternalLinks}
|
|
134
|
+
</span>
|
|
113
135
|
</div>
|
|
114
136
|
<div className="flex items-center justify-between">
|
|
115
137
|
<div className="flex items-center gap-2">
|
|
@@ -130,5 +152,5 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
130
152
|
</div>
|
|
131
153
|
</div>
|
|
132
154
|
</div>
|
|
133
|
-
)
|
|
155
|
+
)
|
|
134
156
|
}
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
|
3
|
+
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react'
|
|
4
4
|
|
|
5
|
-
type Theme = 'light' | 'dark' | 'system'
|
|
5
|
+
type Theme = 'light' | 'dark' | 'system'
|
|
6
6
|
|
|
7
7
|
interface ThemeContextValue {
|
|
8
|
-
theme: Theme
|
|
9
|
-
resolvedTheme: 'light' | 'dark'
|
|
10
|
-
setTheme: (theme: Theme) => void
|
|
8
|
+
theme: Theme
|
|
9
|
+
resolvedTheme: 'light' | 'dark'
|
|
10
|
+
setTheme: (theme: Theme) => void
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const ThemeContext = createContext<ThemeContextValue>({
|
|
14
14
|
theme: 'system',
|
|
15
15
|
resolvedTheme: 'light',
|
|
16
16
|
setTheme: () => {},
|
|
17
|
-
})
|
|
17
|
+
})
|
|
18
18
|
|
|
19
19
|
export function useTheme() {
|
|
20
|
-
return useContext(ThemeContext)
|
|
20
|
+
return useContext(ThemeContext)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
function getSystemTheme(): 'light' | 'dark' {
|
|
24
|
-
if (typeof window === 'undefined') return 'light'
|
|
25
|
-
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
24
|
+
if (typeof window === 'undefined') return 'light'
|
|
25
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
function resolveTheme(theme: Theme): 'light' | 'dark' {
|
|
29
|
-
return theme === 'system' ? getSystemTheme() : theme
|
|
29
|
+
return theme === 'system' ? getSystemTheme() : theme
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
const STORAGE_KEY = 'actuate-theme'
|
|
32
|
+
const STORAGE_KEY = 'actuate-theme'
|
|
33
33
|
|
|
34
34
|
interface ThemeProviderProps {
|
|
35
|
-
children: ReactNode
|
|
35
|
+
children: ReactNode
|
|
36
36
|
/** When true, default to dark mode if the user hasn't explicitly chosen a theme. */
|
|
37
|
-
defaultDarkMode?: boolean
|
|
37
|
+
defaultDarkMode?: boolean
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
export function ThemeProvider({ children, defaultDarkMode }: ThemeProviderProps) {
|
|
41
|
-
const [theme, setThemeState] = useState<Theme>('system')
|
|
42
|
-
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light')
|
|
41
|
+
const [theme, setThemeState] = useState<Theme>('system')
|
|
42
|
+
const [resolvedTheme, setResolvedTheme] = useState<'light' | 'dark'>('light')
|
|
43
43
|
|
|
44
44
|
useEffect(() => {
|
|
45
|
-
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null
|
|
46
|
-
let initial: Theme
|
|
45
|
+
const stored = localStorage.getItem(STORAGE_KEY) as Theme | null
|
|
46
|
+
let initial: Theme
|
|
47
47
|
if (stored && ['light', 'dark', 'system'].includes(stored)) {
|
|
48
|
-
initial = stored
|
|
48
|
+
initial = stored
|
|
49
49
|
} else if (defaultDarkMode === true) {
|
|
50
|
-
initial = 'dark'
|
|
50
|
+
initial = 'dark'
|
|
51
51
|
} else if (defaultDarkMode === false) {
|
|
52
|
-
initial = 'light'
|
|
52
|
+
initial = 'light'
|
|
53
53
|
} else {
|
|
54
|
-
initial = 'system'
|
|
54
|
+
initial = 'system'
|
|
55
55
|
}
|
|
56
|
-
setThemeState(initial)
|
|
57
|
-
const resolved = resolveTheme(initial)
|
|
58
|
-
setResolvedTheme(resolved)
|
|
59
|
-
applyTheme(resolved)
|
|
60
|
-
}, [defaultDarkMode])
|
|
56
|
+
setThemeState(initial)
|
|
57
|
+
const resolved = resolveTheme(initial)
|
|
58
|
+
setResolvedTheme(resolved)
|
|
59
|
+
applyTheme(resolved)
|
|
60
|
+
}, [defaultDarkMode])
|
|
61
61
|
|
|
62
62
|
useEffect(() => {
|
|
63
|
-
const mq = window.matchMedia('(prefers-color-scheme: dark)')
|
|
63
|
+
const mq = window.matchMedia('(prefers-color-scheme: dark)')
|
|
64
64
|
const handler = () => {
|
|
65
65
|
if (theme === 'system') {
|
|
66
|
-
const resolved = getSystemTheme()
|
|
67
|
-
setResolvedTheme(resolved)
|
|
68
|
-
applyTheme(resolved)
|
|
66
|
+
const resolved = getSystemTheme()
|
|
67
|
+
setResolvedTheme(resolved)
|
|
68
|
+
applyTheme(resolved)
|
|
69
69
|
}
|
|
70
|
-
}
|
|
71
|
-
mq.addEventListener('change', handler)
|
|
72
|
-
return () => mq.removeEventListener('change', handler)
|
|
73
|
-
}, [theme])
|
|
70
|
+
}
|
|
71
|
+
mq.addEventListener('change', handler)
|
|
72
|
+
return () => mq.removeEventListener('change', handler)
|
|
73
|
+
}, [theme])
|
|
74
74
|
|
|
75
75
|
const setTheme = useCallback((next: Theme) => {
|
|
76
|
-
setThemeState(next)
|
|
77
|
-
localStorage.setItem(STORAGE_KEY, next)
|
|
78
|
-
const resolved = resolveTheme(next)
|
|
79
|
-
setResolvedTheme(resolved)
|
|
80
|
-
applyTheme(resolved)
|
|
81
|
-
}, [])
|
|
76
|
+
setThemeState(next)
|
|
77
|
+
localStorage.setItem(STORAGE_KEY, next)
|
|
78
|
+
const resolved = resolveTheme(next)
|
|
79
|
+
setResolvedTheme(resolved)
|
|
80
|
+
applyTheme(resolved)
|
|
81
|
+
}, [])
|
|
82
82
|
|
|
83
83
|
return (
|
|
84
84
|
<ThemeContext.Provider value={{ theme, resolvedTheme, setTheme }}>
|
|
85
85
|
{children}
|
|
86
86
|
</ThemeContext.Provider>
|
|
87
|
-
)
|
|
87
|
+
)
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
function applyTheme(resolved: 'light' | 'dark') {
|
|
91
|
-
const adminRoot = document.querySelector('.actuate-admin')
|
|
92
|
-
if (!adminRoot) return
|
|
91
|
+
const adminRoot = document.querySelector('.actuate-admin')
|
|
92
|
+
if (!adminRoot) return
|
|
93
93
|
if (resolved === 'dark') {
|
|
94
|
-
adminRoot.classList.add('dark')
|
|
94
|
+
adminRoot.classList.add('dark')
|
|
95
95
|
} else {
|
|
96
|
-
adminRoot.classList.remove('dark')
|
|
96
|
+
adminRoot.classList.remove('dark')
|
|
97
97
|
}
|
|
98
98
|
}
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import React, { useState } from 'react'
|
|
4
|
-
import { useEditor, EditorContent, type Editor } from '@tiptap/react'
|
|
5
|
-
import { MediaPickerModal } from './MediaPickerModal.js'
|
|
6
|
-
import StarterKit from '@tiptap/starter-kit'
|
|
7
|
-
import UnderlineExt from '@tiptap/extension-underline'
|
|
8
|
-
import Link from '@tiptap/extension-link'
|
|
9
|
-
import Image from '@tiptap/extension-image'
|
|
10
|
-
import Table from '@tiptap/extension-table'
|
|
11
|
-
import TableRow from '@tiptap/extension-table-row'
|
|
12
|
-
import TableHeader from '@tiptap/extension-table-header'
|
|
13
|
-
import TableCell from '@tiptap/extension-table-cell'
|
|
14
|
-
import TextAlign from '@tiptap/extension-text-align'
|
|
15
|
-
import Placeholder from '@tiptap/extension-placeholder'
|
|
16
|
-
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
|
|
17
|
-
import HorizontalRule from '@tiptap/extension-horizontal-rule'
|
|
18
|
-
import { common, createLowlight } from 'lowlight'
|
|
3
|
+
import React, { useState } from 'react'
|
|
4
|
+
import { useEditor, EditorContent, type Editor } from '@tiptap/react'
|
|
5
|
+
import { MediaPickerModal } from './MediaPickerModal.js'
|
|
6
|
+
import StarterKit from '@tiptap/starter-kit'
|
|
7
|
+
import UnderlineExt from '@tiptap/extension-underline'
|
|
8
|
+
import Link from '@tiptap/extension-link'
|
|
9
|
+
import Image from '@tiptap/extension-image'
|
|
10
|
+
import Table from '@tiptap/extension-table'
|
|
11
|
+
import TableRow from '@tiptap/extension-table-row'
|
|
12
|
+
import TableHeader from '@tiptap/extension-table-header'
|
|
13
|
+
import TableCell from '@tiptap/extension-table-cell'
|
|
14
|
+
import TextAlign from '@tiptap/extension-text-align'
|
|
15
|
+
import Placeholder from '@tiptap/extension-placeholder'
|
|
16
|
+
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
|
|
17
|
+
import HorizontalRule from '@tiptap/extension-horizontal-rule'
|
|
18
|
+
import { common, createLowlight } from 'lowlight'
|
|
19
19
|
import {
|
|
20
20
|
Bold,
|
|
21
21
|
Italic,
|
|
@@ -41,16 +41,16 @@ import {
|
|
|
41
41
|
Trash2,
|
|
42
42
|
Undo,
|
|
43
43
|
Redo,
|
|
44
|
-
} from 'lucide-react'
|
|
44
|
+
} from 'lucide-react'
|
|
45
45
|
|
|
46
|
-
const lowlight = createLowlight(common)
|
|
46
|
+
const lowlight = createLowlight(common)
|
|
47
47
|
|
|
48
48
|
export interface TipTapEditorProps {
|
|
49
|
-
content: string
|
|
50
|
-
onChange: (html: string) => void
|
|
51
|
-
placeholder?: string
|
|
52
|
-
editable?: boolean
|
|
53
|
-
className?: string
|
|
49
|
+
content: string
|
|
50
|
+
onChange: (html: string) => void
|
|
51
|
+
placeholder?: string
|
|
52
|
+
editable?: boolean
|
|
53
|
+
className?: string
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
const editorStyles = `
|
|
@@ -131,7 +131,7 @@ const editorStyles = `
|
|
|
131
131
|
.ProseMirror .selectedCell {
|
|
132
132
|
background-color: #dbeafe;
|
|
133
133
|
}
|
|
134
|
-
|
|
134
|
+
`
|
|
135
135
|
|
|
136
136
|
function ToolbarButton({
|
|
137
137
|
onClick,
|
|
@@ -140,11 +140,11 @@ function ToolbarButton({
|
|
|
140
140
|
title,
|
|
141
141
|
children,
|
|
142
142
|
}: {
|
|
143
|
-
onClick: () => void
|
|
144
|
-
isActive?: boolean
|
|
145
|
-
disabled?: boolean
|
|
146
|
-
title: string
|
|
147
|
-
children: React.ReactNode
|
|
143
|
+
onClick: () => void
|
|
144
|
+
isActive?: boolean
|
|
145
|
+
disabled?: boolean
|
|
146
|
+
title: string
|
|
147
|
+
children: React.ReactNode
|
|
148
148
|
}) {
|
|
149
149
|
return (
|
|
150
150
|
<button
|
|
@@ -160,30 +160,30 @@ function ToolbarButton({
|
|
|
160
160
|
>
|
|
161
161
|
{children}
|
|
162
162
|
</button>
|
|
163
|
-
)
|
|
163
|
+
)
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
function Divider() {
|
|
167
|
-
return <div className="w-px h-6 bg-gray-200 mx-1"
|
|
167
|
+
return <div className="w-px h-6 bg-gray-200 mx-1" />
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPicker: () => void }) {
|
|
171
171
|
const addLink = () => {
|
|
172
|
-
const previousUrl = editor.getAttributes('link').href ?? ''
|
|
173
|
-
const url = window.prompt('Enter URL:', previousUrl)
|
|
174
|
-
if (url === null) return
|
|
172
|
+
const previousUrl = editor.getAttributes('link').href ?? ''
|
|
173
|
+
const url = window.prompt('Enter URL:', previousUrl)
|
|
174
|
+
if (url === null) return
|
|
175
175
|
if (url === '') {
|
|
176
|
-
editor.chain().focus().extendMarkRange('link').unsetLink().run()
|
|
177
|
-
return
|
|
176
|
+
editor.chain().focus().extendMarkRange('link').unsetLink().run()
|
|
177
|
+
return
|
|
178
178
|
}
|
|
179
|
-
editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
|
|
180
|
-
}
|
|
179
|
+
editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
|
|
180
|
+
}
|
|
181
181
|
|
|
182
182
|
const insertTable = () => {
|
|
183
|
-
editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
|
|
184
|
-
}
|
|
183
|
+
editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
|
|
184
|
+
}
|
|
185
185
|
|
|
186
|
-
const isInTable = editor.isActive('table')
|
|
186
|
+
const isInTable = editor.isActive('table')
|
|
187
187
|
|
|
188
188
|
return (
|
|
189
189
|
<div className="border-b border-gray-200 bg-gray-50 p-2 flex items-center gap-0.5 flex-wrap sticky top-0 z-10">
|
|
@@ -315,23 +315,13 @@ function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPic
|
|
|
315
315
|
<Divider />
|
|
316
316
|
|
|
317
317
|
{/* Group 5: Insert */}
|
|
318
|
-
<ToolbarButton
|
|
319
|
-
onClick={addLink}
|
|
320
|
-
isActive={editor.isActive('link')}
|
|
321
|
-
title="Insert link"
|
|
322
|
-
>
|
|
318
|
+
<ToolbarButton onClick={addLink} isActive={editor.isActive('link')} title="Insert link">
|
|
323
319
|
<LinkIcon className="w-4 h-4" />
|
|
324
320
|
</ToolbarButton>
|
|
325
|
-
<ToolbarButton
|
|
326
|
-
onClick={onOpenMediaPicker}
|
|
327
|
-
title="Insert image"
|
|
328
|
-
>
|
|
321
|
+
<ToolbarButton onClick={onOpenMediaPicker} title="Insert image">
|
|
329
322
|
<ImageIcon className="w-4 h-4" />
|
|
330
323
|
</ToolbarButton>
|
|
331
|
-
<ToolbarButton
|
|
332
|
-
onClick={insertTable}
|
|
333
|
-
title="Insert table (3×3)"
|
|
334
|
-
>
|
|
324
|
+
<ToolbarButton onClick={insertTable} title="Insert table (3×3)">
|
|
335
325
|
<TableIcon className="w-4 h-4" />
|
|
336
326
|
</ToolbarButton>
|
|
337
327
|
|
|
@@ -402,7 +392,7 @@ function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPic
|
|
|
402
392
|
<Redo className="w-4 h-4" />
|
|
403
393
|
</ToolbarButton>
|
|
404
394
|
</div>
|
|
405
|
-
)
|
|
395
|
+
)
|
|
406
396
|
}
|
|
407
397
|
|
|
408
398
|
export function TipTapEditor({
|
|
@@ -412,7 +402,7 @@ export function TipTapEditor({
|
|
|
412
402
|
editable = true,
|
|
413
403
|
className,
|
|
414
404
|
}: TipTapEditorProps) {
|
|
415
|
-
const [mediaPickerOpen, setMediaPickerOpen] = useState(false)
|
|
405
|
+
const [mediaPickerOpen, setMediaPickerOpen] = useState(false)
|
|
416
406
|
|
|
417
407
|
const editor = useEditor({
|
|
418
408
|
extensions: [
|
|
@@ -443,18 +433,24 @@ export function TipTapEditor({
|
|
|
443
433
|
content,
|
|
444
434
|
editable: editable !== false,
|
|
445
435
|
onUpdate: ({ editor: ed }) => {
|
|
446
|
-
onChange(ed.getHTML())
|
|
436
|
+
onChange(ed.getHTML())
|
|
447
437
|
},
|
|
448
|
-
})
|
|
438
|
+
})
|
|
449
439
|
|
|
450
|
-
if (!editor) return null
|
|
440
|
+
if (!editor) return null
|
|
451
441
|
|
|
452
442
|
const handleImageSelected = (url: string, alt?: string) => {
|
|
453
|
-
editor
|
|
454
|
-
|
|
443
|
+
editor
|
|
444
|
+
.chain()
|
|
445
|
+
.focus()
|
|
446
|
+
.setImage({ src: url, alt: alt ?? '' })
|
|
447
|
+
.run()
|
|
448
|
+
}
|
|
455
449
|
|
|
456
450
|
return (
|
|
457
|
-
<div
|
|
451
|
+
<div
|
|
452
|
+
className={`border border-gray-200 rounded-lg overflow-hidden bg-white ${className ?? ''}`}
|
|
453
|
+
>
|
|
458
454
|
{editable && <Toolbar editor={editor} onOpenMediaPicker={() => setMediaPickerOpen(true)} />}
|
|
459
455
|
<EditorContent editor={editor} />
|
|
460
456
|
<style dangerouslySetInnerHTML={{ __html: editorStyles }} />
|
|
@@ -465,5 +461,5 @@ export function TipTapEditor({
|
|
|
465
461
|
accept="image/*"
|
|
466
462
|
/>
|
|
467
463
|
</div>
|
|
468
|
-
)
|
|
464
|
+
)
|
|
469
465
|
}
|