@actuate-media/cms-admin 0.7.3 → 0.8.1
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 +95 -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.d.ts.map +1 -1
- package/dist/lib/api.js +33 -4
- 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 +39 -16
- 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 +94 -3
- 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 +25 -3
- 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 +302 -177
- 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 +58 -30
- 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 +7 -1
- 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 +589 -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 +258 -81
- 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 +164 -146
- 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,6 +1,6 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useCallback } from 'react'
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
4
4
|
import {
|
|
5
5
|
Plus,
|
|
6
6
|
ArrowLeft,
|
|
@@ -12,99 +12,94 @@ import {
|
|
|
12
12
|
AlertTriangle,
|
|
13
13
|
Calendar,
|
|
14
14
|
Hash,
|
|
15
|
-
} from 'lucide-react'
|
|
16
|
-
import { toast } from 'sonner'
|
|
17
|
-
import { cmsApi } from '../../lib/api.js'
|
|
18
|
-
import { createSection, createContainer, createRow, createColumn } from '@actuate-media/cms-core'
|
|
15
|
+
} from 'lucide-react'
|
|
16
|
+
import { toast } from 'sonner'
|
|
17
|
+
import { cmsApi } from '../../lib/api.js'
|
|
18
|
+
import { createSection, createContainer, createRow, createColumn } from '@actuate-media/cms-core'
|
|
19
19
|
|
|
20
20
|
export interface SavedSectionsProps {
|
|
21
|
-
onNavigate: (path: string) => void
|
|
22
|
-
config: any
|
|
21
|
+
onNavigate: (path: string) => void
|
|
22
|
+
config: any
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
interface SavedSection {
|
|
26
|
-
id: string
|
|
27
|
-
name: string
|
|
28
|
-
description: string
|
|
29
|
-
category: string
|
|
30
|
-
tree: Record<string, unknown> | null
|
|
31
|
-
usageCount: number
|
|
32
|
-
createdAt: string
|
|
33
|
-
updatedAt: string
|
|
26
|
+
id: string
|
|
27
|
+
name: string
|
|
28
|
+
description: string
|
|
29
|
+
category: string
|
|
30
|
+
tree: Record<string, unknown> | null
|
|
31
|
+
usageCount: number
|
|
32
|
+
createdAt: string
|
|
33
|
+
updatedAt: string
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
type ViewState =
|
|
37
|
-
| { mode: 'list' }
|
|
38
|
-
| { mode: 'create' }
|
|
39
|
-
| { mode: 'edit'; section: SavedSection };
|
|
36
|
+
type ViewState = { mode: 'list' } | { mode: 'create' } | { mode: 'edit'; section: SavedSection }
|
|
40
37
|
|
|
41
|
-
const CATEGORIES = ['header', 'footer', 'content', 'sidebar'] as const
|
|
42
|
-
type Category = (typeof CATEGORIES)[number]
|
|
38
|
+
const CATEGORIES = ['header', 'footer', 'content', 'sidebar'] as const
|
|
39
|
+
type Category = (typeof CATEGORIES)[number]
|
|
43
40
|
|
|
44
41
|
const CATEGORY_COLORS: Record<string, string> = {
|
|
45
42
|
header: 'bg-primary/10 text-primary',
|
|
46
43
|
footer: 'bg-accent text-foreground',
|
|
47
44
|
content: 'bg-muted text-muted-foreground',
|
|
48
45
|
sidebar: 'bg-primary/10 text-primary',
|
|
49
|
-
}
|
|
46
|
+
}
|
|
50
47
|
|
|
51
48
|
function formatDate(dateStr: string): string {
|
|
52
49
|
return new Date(dateStr).toLocaleDateString(undefined, {
|
|
53
50
|
month: 'short',
|
|
54
51
|
day: 'numeric',
|
|
55
52
|
year: 'numeric',
|
|
56
|
-
})
|
|
53
|
+
})
|
|
57
54
|
}
|
|
58
55
|
|
|
59
56
|
function createEmptySectionTree(): Record<string, unknown> {
|
|
60
|
-
const col = createColumn(100)
|
|
61
|
-
const row = createRow([col])
|
|
62
|
-
const container = createContainer()
|
|
63
|
-
(container as unknown as { children: unknown[] }).children = [row]
|
|
64
|
-
const section = createSection()
|
|
65
|
-
(section as unknown as { children: unknown[] }).children = [container]
|
|
66
|
-
return section as unknown as Record<string, unknown
|
|
57
|
+
const col = createColumn(100)
|
|
58
|
+
const row = createRow([col])
|
|
59
|
+
const container = createContainer()
|
|
60
|
+
;(container as unknown as { children: unknown[] }).children = [row]
|
|
61
|
+
const section = createSection()
|
|
62
|
+
;(section as unknown as { children: unknown[] }).children = [container]
|
|
63
|
+
return section as unknown as Record<string, unknown>
|
|
67
64
|
}
|
|
68
65
|
|
|
69
66
|
export function SavedSections({ onNavigate, config }: SavedSectionsProps) {
|
|
70
|
-
const [sections, setSections] = useState<SavedSection[]>([])
|
|
71
|
-
const [loading, setLoading] = useState(true)
|
|
72
|
-
const [error, setError] = useState<string | null>(null)
|
|
73
|
-
const [viewState, setViewState] = useState<ViewState>({ mode: 'list' })
|
|
74
|
-
const [activeCategory, setActiveCategory] = useState<Category | 'all'>('all')
|
|
75
|
-
const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null)
|
|
76
|
-
const [saving, setSaving] = useState(false)
|
|
67
|
+
const [sections, setSections] = useState<SavedSection[]>([])
|
|
68
|
+
const [loading, setLoading] = useState(true)
|
|
69
|
+
const [error, setError] = useState<string | null>(null)
|
|
70
|
+
const [viewState, setViewState] = useState<ViewState>({ mode: 'list' })
|
|
71
|
+
const [activeCategory, setActiveCategory] = useState<Category | 'all'>('all')
|
|
72
|
+
const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null)
|
|
73
|
+
const [saving, setSaving] = useState(false)
|
|
77
74
|
|
|
78
75
|
const fetchSections = useCallback(async () => {
|
|
79
|
-
setLoading(true)
|
|
80
|
-
setError(null)
|
|
81
|
-
const res = await cmsApi<SavedSection[]>('/saved-sections')
|
|
76
|
+
setLoading(true)
|
|
77
|
+
setError(null)
|
|
78
|
+
const res = await cmsApi<SavedSection[]>('/saved-sections')
|
|
82
79
|
if (res.error) {
|
|
83
|
-
setError(res.error)
|
|
80
|
+
setError(res.error)
|
|
84
81
|
} else {
|
|
85
|
-
setSections(res.data ?? [])
|
|
82
|
+
setSections(res.data ?? [])
|
|
86
83
|
}
|
|
87
|
-
setLoading(false)
|
|
88
|
-
}, [])
|
|
84
|
+
setLoading(false)
|
|
85
|
+
}, [])
|
|
89
86
|
|
|
90
87
|
useEffect(() => {
|
|
91
|
-
fetchSections()
|
|
92
|
-
}, [fetchSections])
|
|
88
|
+
fetchSections()
|
|
89
|
+
}, [fetchSections])
|
|
93
90
|
|
|
94
91
|
const filteredSections =
|
|
95
|
-
activeCategory === 'all'
|
|
96
|
-
? sections
|
|
97
|
-
: sections.filter((s) => s.category === activeCategory);
|
|
92
|
+
activeCategory === 'all' ? sections : sections.filter((s) => s.category === activeCategory)
|
|
98
93
|
|
|
99
94
|
async function handleDelete(id: string) {
|
|
100
|
-
const res = await cmsApi(`/saved-sections/${id}`, { method: 'DELETE' })
|
|
95
|
+
const res = await cmsApi(`/saved-sections/${id}`, { method: 'DELETE' })
|
|
101
96
|
if (res.error) {
|
|
102
|
-
toast.error(res.error)
|
|
97
|
+
toast.error(res.error)
|
|
103
98
|
} else {
|
|
104
|
-
toast.success('Section deleted')
|
|
105
|
-
setSections((prev) => prev.filter((s) => s.id !== id))
|
|
99
|
+
toast.success('Section deleted')
|
|
100
|
+
setSections((prev) => prev.filter((s) => s.id !== id))
|
|
106
101
|
}
|
|
107
|
-
setDeleteConfirmId(null)
|
|
102
|
+
setDeleteConfirmId(null)
|
|
108
103
|
}
|
|
109
104
|
|
|
110
105
|
async function handleDuplicate(section: SavedSection) {
|
|
@@ -116,12 +111,12 @@ export function SavedSections({ onNavigate, config }: SavedSectionsProps) {
|
|
|
116
111
|
category: section.category,
|
|
117
112
|
tree: section.tree,
|
|
118
113
|
}),
|
|
119
|
-
})
|
|
114
|
+
})
|
|
120
115
|
if (res.error) {
|
|
121
|
-
toast.error(res.error)
|
|
116
|
+
toast.error(res.error)
|
|
122
117
|
} else {
|
|
123
|
-
toast.success('Section duplicated')
|
|
124
|
-
fetchSections()
|
|
118
|
+
toast.success('Section duplicated')
|
|
119
|
+
fetchSections()
|
|
125
120
|
}
|
|
126
121
|
}
|
|
127
122
|
|
|
@@ -131,41 +126,38 @@ export function SavedSections({ onNavigate, config }: SavedSectionsProps) {
|
|
|
131
126
|
initial={viewState.mode === 'edit' ? viewState.section : undefined}
|
|
132
127
|
saving={saving}
|
|
133
128
|
onSave={async (data) => {
|
|
134
|
-
setSaving(true)
|
|
129
|
+
setSaving(true)
|
|
135
130
|
if (viewState.mode === 'create') {
|
|
136
131
|
const res = await cmsApi<SavedSection>('/saved-sections', {
|
|
137
132
|
method: 'POST',
|
|
138
133
|
body: JSON.stringify({ ...data, tree: createEmptySectionTree() }),
|
|
139
|
-
})
|
|
140
|
-
setSaving(false)
|
|
134
|
+
})
|
|
135
|
+
setSaving(false)
|
|
141
136
|
if (res.error) {
|
|
142
|
-
toast.error(res.error)
|
|
137
|
+
toast.error(res.error)
|
|
143
138
|
} else {
|
|
144
|
-
toast.success('Section created')
|
|
145
|
-
setViewState({ mode: 'list' })
|
|
146
|
-
fetchSections()
|
|
139
|
+
toast.success('Section created')
|
|
140
|
+
setViewState({ mode: 'list' })
|
|
141
|
+
fetchSections()
|
|
147
142
|
}
|
|
148
143
|
} else {
|
|
149
|
-
const res = await cmsApi<SavedSection>(
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
);
|
|
156
|
-
setSaving(false);
|
|
144
|
+
const res = await cmsApi<SavedSection>(`/saved-sections/${viewState.section.id}`, {
|
|
145
|
+
method: 'PUT',
|
|
146
|
+
body: JSON.stringify(data),
|
|
147
|
+
})
|
|
148
|
+
setSaving(false)
|
|
157
149
|
if (res.error) {
|
|
158
|
-
toast.error(res.error)
|
|
150
|
+
toast.error(res.error)
|
|
159
151
|
} else {
|
|
160
|
-
toast.success('Section updated')
|
|
161
|
-
setViewState({ mode: 'list' })
|
|
162
|
-
fetchSections()
|
|
152
|
+
toast.success('Section updated')
|
|
153
|
+
setViewState({ mode: 'list' })
|
|
154
|
+
fetchSections()
|
|
163
155
|
}
|
|
164
156
|
}
|
|
165
157
|
}}
|
|
166
158
|
onCancel={() => setViewState({ mode: 'list' })}
|
|
167
159
|
/>
|
|
168
|
-
)
|
|
160
|
+
)
|
|
169
161
|
}
|
|
170
162
|
|
|
171
163
|
return (
|
|
@@ -254,9 +246,7 @@ export function SavedSections({ onNavigate, config }: SavedSectionsProps) {
|
|
|
254
246
|
>
|
|
255
247
|
<div className="flex items-start justify-between gap-3">
|
|
256
248
|
<div className="min-w-0 flex-1">
|
|
257
|
-
<p className="text-sm font-medium text-foreground truncate">
|
|
258
|
-
{section.name}
|
|
259
|
-
</p>
|
|
249
|
+
<p className="text-sm font-medium text-foreground truncate">{section.name}</p>
|
|
260
250
|
{section.description && (
|
|
261
251
|
<p className="text-xs text-muted-foreground mt-0.5 line-clamp-2">
|
|
262
252
|
{section.description}
|
|
@@ -341,13 +331,13 @@ export function SavedSections({ onNavigate, config }: SavedSectionsProps) {
|
|
|
341
331
|
</div>
|
|
342
332
|
)}
|
|
343
333
|
</div>
|
|
344
|
-
)
|
|
334
|
+
)
|
|
345
335
|
}
|
|
346
336
|
|
|
347
337
|
interface CategoryTabProps {
|
|
348
|
-
label: string
|
|
349
|
-
active: boolean
|
|
350
|
-
onClick: () => void
|
|
338
|
+
label: string
|
|
339
|
+
active: boolean
|
|
340
|
+
onClick: () => void
|
|
351
341
|
}
|
|
352
342
|
|
|
353
343
|
function CategoryTab({ label, active, onClick }: CategoryTabProps) {
|
|
@@ -363,30 +353,28 @@ function CategoryTab({ label, active, onClick }: CategoryTabProps) {
|
|
|
363
353
|
>
|
|
364
354
|
{label}
|
|
365
355
|
</button>
|
|
366
|
-
)
|
|
356
|
+
)
|
|
367
357
|
}
|
|
368
358
|
|
|
369
359
|
interface SectionFormProps {
|
|
370
|
-
initial?: SavedSection
|
|
371
|
-
saving: boolean
|
|
372
|
-
onSave: (data: { name: string; description: string; category: string }) => void
|
|
373
|
-
onCancel: () => void
|
|
360
|
+
initial?: SavedSection
|
|
361
|
+
saving: boolean
|
|
362
|
+
onSave: (data: { name: string; description: string; category: string }) => void
|
|
363
|
+
onCancel: () => void
|
|
374
364
|
}
|
|
375
365
|
|
|
376
366
|
function SectionForm({ initial, saving, onSave, onCancel }: SectionFormProps) {
|
|
377
|
-
const [name, setName] = useState(initial?.name ?? '')
|
|
378
|
-
const [description, setDescription] = useState(initial?.description ?? '')
|
|
379
|
-
const [category, setCategory] = useState(initial?.category ?? 'content')
|
|
367
|
+
const [name, setName] = useState(initial?.name ?? '')
|
|
368
|
+
const [description, setDescription] = useState(initial?.description ?? '')
|
|
369
|
+
const [category, setCategory] = useState(initial?.category ?? 'content')
|
|
380
370
|
|
|
381
371
|
function handleSubmit(e: React.FormEvent) {
|
|
382
|
-
e.preventDefault()
|
|
383
|
-
if (!name.trim()) return
|
|
384
|
-
onSave({ name: name.trim(), description: description.trim(), category })
|
|
372
|
+
e.preventDefault()
|
|
373
|
+
if (!name.trim()) return
|
|
374
|
+
onSave({ name: name.trim(), description: description.trim(), category })
|
|
385
375
|
}
|
|
386
376
|
|
|
387
|
-
const treeSize = initial?.tree
|
|
388
|
-
? JSON.stringify(initial.tree).length
|
|
389
|
-
: null;
|
|
377
|
+
const treeSize = initial?.tree ? JSON.stringify(initial.tree).length : null
|
|
390
378
|
|
|
391
379
|
return (
|
|
392
380
|
<div className="p-4 pr-8">
|
|
@@ -422,7 +410,10 @@ function SectionForm({ initial, saving, onSave, onCancel }: SectionFormProps) {
|
|
|
422
410
|
</div>
|
|
423
411
|
|
|
424
412
|
<div>
|
|
425
|
-
<label
|
|
413
|
+
<label
|
|
414
|
+
htmlFor="section-description"
|
|
415
|
+
className="block text-sm font-medium text-foreground mb-1"
|
|
416
|
+
>
|
|
426
417
|
Description
|
|
427
418
|
</label>
|
|
428
419
|
<textarea
|
|
@@ -436,7 +427,10 @@ function SectionForm({ initial, saving, onSave, onCancel }: SectionFormProps) {
|
|
|
436
427
|
</div>
|
|
437
428
|
|
|
438
429
|
<div>
|
|
439
|
-
<label
|
|
430
|
+
<label
|
|
431
|
+
htmlFor="section-category"
|
|
432
|
+
className="block text-sm font-medium text-foreground mb-1"
|
|
433
|
+
>
|
|
440
434
|
Category
|
|
441
435
|
</label>
|
|
442
436
|
<select
|
|
@@ -456,8 +450,8 @@ function SectionForm({ initial, saving, onSave, onCancel }: SectionFormProps) {
|
|
|
456
450
|
{treeSize !== null && (
|
|
457
451
|
<div className="rounded-md border border-border bg-muted p-3">
|
|
458
452
|
<p className="text-xs text-muted-foreground">
|
|
459
|
-
Section tree editing is available in the page builder.
|
|
460
|
-
|
|
453
|
+
Section tree editing is available in the page builder. Current tree size:{' '}
|
|
454
|
+
{(treeSize / 1024).toFixed(1)} KB
|
|
461
455
|
</p>
|
|
462
456
|
</div>
|
|
463
457
|
)}
|
|
@@ -482,5 +476,5 @@ function SectionForm({ initial, saving, onSave, onCancel }: SectionFormProps) {
|
|
|
482
476
|
</div>
|
|
483
477
|
</form>
|
|
484
478
|
</div>
|
|
485
|
-
)
|
|
479
|
+
)
|
|
486
480
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import { useState, useEffect, useCallback } from 'react'
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react'
|
|
4
4
|
import {
|
|
5
5
|
X,
|
|
6
6
|
Loader2,
|
|
@@ -11,23 +11,23 @@ import {
|
|
|
11
11
|
Phone,
|
|
12
12
|
BookOpen,
|
|
13
13
|
File,
|
|
14
|
-
} from 'lucide-react'
|
|
15
|
-
import type { LucideIcon } from 'lucide-react'
|
|
16
|
-
import { cmsApi } from '../../lib/api.js'
|
|
17
|
-
import { createEmptyPage } from '@actuate-media/cms-core'
|
|
18
|
-
import type { PageNode } from '@actuate-media/cms-core'
|
|
14
|
+
} from 'lucide-react'
|
|
15
|
+
import type { LucideIcon } from 'lucide-react'
|
|
16
|
+
import { cmsApi } from '../../lib/api.js'
|
|
17
|
+
import { createEmptyPage } from '@actuate-media/cms-core'
|
|
18
|
+
import type { PageNode } from '@actuate-media/cms-core'
|
|
19
19
|
|
|
20
20
|
export interface TemplatePickerProps {
|
|
21
|
-
onSelect: (templateTree: PageNode) => void
|
|
22
|
-
onClose: () => void
|
|
21
|
+
onSelect: (templateTree: PageNode) => void
|
|
22
|
+
onClose: () => void
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
interface PageTemplate {
|
|
26
|
-
id: string
|
|
27
|
-
name: string
|
|
28
|
-
description: string
|
|
29
|
-
category: string
|
|
30
|
-
tree: PageNode
|
|
26
|
+
id: string
|
|
27
|
+
name: string
|
|
28
|
+
description: string
|
|
29
|
+
category: string
|
|
30
|
+
tree: PageNode
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const categoryIcons: Record<string, LucideIcon> = {
|
|
@@ -36,7 +36,7 @@ const categoryIcons: Record<string, LucideIcon> = {
|
|
|
36
36
|
contact: MapPin,
|
|
37
37
|
portfolio: BookOpen,
|
|
38
38
|
mobile: Phone,
|
|
39
|
-
}
|
|
39
|
+
}
|
|
40
40
|
|
|
41
41
|
const categoryColors: Record<string, string> = {
|
|
42
42
|
landing: 'bg-primary/10 text-primary',
|
|
@@ -44,53 +44,53 @@ const categoryColors: Record<string, string> = {
|
|
|
44
44
|
contact: 'bg-primary/10 text-primary',
|
|
45
45
|
portfolio: 'bg-accent text-foreground',
|
|
46
46
|
mobile: 'bg-primary/10 text-primary',
|
|
47
|
-
}
|
|
47
|
+
}
|
|
48
48
|
|
|
49
49
|
function resolveIcon(category: string): LucideIcon {
|
|
50
|
-
return categoryIcons[category] ?? File
|
|
50
|
+
return categoryIcons[category] ?? File
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
function resolveBadgeColor(category: string): string {
|
|
54
|
-
return categoryColors[category] ?? 'bg-muted text-muted-foreground'
|
|
54
|
+
return categoryColors[category] ?? 'bg-muted text-muted-foreground'
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export function TemplatePicker({ onSelect, onClose }: TemplatePickerProps) {
|
|
58
|
-
const [templates, setTemplates] = useState<PageTemplate[]>([])
|
|
59
|
-
const [loading, setLoading] = useState(true)
|
|
60
|
-
const [error, setError] = useState<string | null>(null)
|
|
58
|
+
const [templates, setTemplates] = useState<PageTemplate[]>([])
|
|
59
|
+
const [loading, setLoading] = useState(true)
|
|
60
|
+
const [error, setError] = useState<string | null>(null)
|
|
61
61
|
|
|
62
62
|
const fetchTemplates = useCallback(async () => {
|
|
63
|
-
setLoading(true)
|
|
64
|
-
setError(null)
|
|
65
|
-
const res = await cmsApi<PageTemplate[]>('/page-templates')
|
|
63
|
+
setLoading(true)
|
|
64
|
+
setError(null)
|
|
65
|
+
const res = await cmsApi<PageTemplate[]>('/page-templates')
|
|
66
66
|
if (res.error) {
|
|
67
|
-
setError(res.error)
|
|
67
|
+
setError(res.error)
|
|
68
68
|
} else {
|
|
69
|
-
setTemplates(res.data ?? [])
|
|
69
|
+
setTemplates(res.data ?? [])
|
|
70
70
|
}
|
|
71
|
-
setLoading(false)
|
|
72
|
-
}, [])
|
|
71
|
+
setLoading(false)
|
|
72
|
+
}, [])
|
|
73
73
|
|
|
74
74
|
useEffect(() => {
|
|
75
|
-
fetchTemplates()
|
|
76
|
-
}, [fetchTemplates])
|
|
75
|
+
fetchTemplates()
|
|
76
|
+
}, [fetchTemplates])
|
|
77
77
|
|
|
78
78
|
useEffect(() => {
|
|
79
79
|
function handleKeyDown(e: KeyboardEvent) {
|
|
80
|
-
if (e.key === 'Escape') onClose()
|
|
80
|
+
if (e.key === 'Escape') onClose()
|
|
81
81
|
}
|
|
82
|
-
document.addEventListener('keydown', handleKeyDown)
|
|
83
|
-
return () => document.removeEventListener('keydown', handleKeyDown)
|
|
84
|
-
}, [onClose])
|
|
82
|
+
document.addEventListener('keydown', handleKeyDown)
|
|
83
|
+
return () => document.removeEventListener('keydown', handleKeyDown)
|
|
84
|
+
}, [onClose])
|
|
85
85
|
|
|
86
86
|
function handleBlankPage() {
|
|
87
|
-
onSelect(createEmptyPage())
|
|
88
|
-
onClose()
|
|
87
|
+
onSelect(createEmptyPage())
|
|
88
|
+
onClose()
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
function handleTemplateSelect(template: PageTemplate) {
|
|
92
|
-
onSelect(template.tree)
|
|
93
|
-
onClose()
|
|
92
|
+
onSelect(template.tree)
|
|
93
|
+
onClose()
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
return (
|
|
@@ -156,14 +156,12 @@ export function TemplatePicker({ onSelect, onClose }: TemplatePickerProps) {
|
|
|
156
156
|
<File size={20} />
|
|
157
157
|
</div>
|
|
158
158
|
<p className="text-sm font-medium text-foreground text-center">Blank Page</p>
|
|
159
|
-
<p className="text-xs text-muted-foreground text-center">
|
|
160
|
-
Start from scratch
|
|
161
|
-
</p>
|
|
159
|
+
<p className="text-xs text-muted-foreground text-center">Start from scratch</p>
|
|
162
160
|
</button>
|
|
163
161
|
|
|
164
162
|
{templates.map((template) => {
|
|
165
|
-
const Icon = resolveIcon(template.category)
|
|
166
|
-
const badgeColor = resolveBadgeColor(template.category)
|
|
163
|
+
const Icon = resolveIcon(template.category)
|
|
164
|
+
const badgeColor = resolveBadgeColor(template.category)
|
|
167
165
|
|
|
168
166
|
return (
|
|
169
167
|
<button
|
|
@@ -184,18 +182,16 @@ export function TemplatePicker({ onSelect, onClose }: TemplatePickerProps) {
|
|
|
184
182
|
{template.description}
|
|
185
183
|
</p>
|
|
186
184
|
)}
|
|
187
|
-
<span
|
|
188
|
-
className={`inline-block text-xs px-2 py-0.5 rounded-full ${badgeColor}`}
|
|
189
|
-
>
|
|
185
|
+
<span className={`inline-block text-xs px-2 py-0.5 rounded-full ${badgeColor}`}>
|
|
190
186
|
{template.category}
|
|
191
187
|
</span>
|
|
192
188
|
</button>
|
|
193
|
-
)
|
|
189
|
+
)
|
|
194
190
|
})}
|
|
195
191
|
</div>
|
|
196
192
|
)}
|
|
197
193
|
</div>
|
|
198
194
|
</div>
|
|
199
195
|
</div>
|
|
200
|
-
)
|
|
196
|
+
)
|
|
201
197
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import type { BlockPreviewProps } from './index.js'
|
|
3
|
+
import type { BlockPreviewProps } from './index.js'
|
|
4
4
|
|
|
5
5
|
export function CTAPreview({ data, variant = 'banner' }: BlockPreviewProps) {
|
|
6
|
-
const heading = (data.heading as string) || ''
|
|
7
|
-
const body = (data.body as string) || ''
|
|
8
|
-
const buttonText = (data.buttonText as string) || ''
|
|
6
|
+
const heading = (data.heading as string) || ''
|
|
7
|
+
const body = (data.body as string) || ''
|
|
8
|
+
const buttonText = (data.buttonText as string) || ''
|
|
9
9
|
|
|
10
10
|
const button = (
|
|
11
11
|
<span className="inline-block rounded-md bg-primary px-4 py-2 text-sm text-primary-foreground">
|
|
12
12
|
{buttonText || 'Click Here'}
|
|
13
13
|
</span>
|
|
14
|
-
)
|
|
14
|
+
)
|
|
15
15
|
|
|
16
16
|
if (variant === 'inline') {
|
|
17
17
|
return (
|
|
@@ -20,13 +20,11 @@ export function CTAPreview({ data, variant = 'banner' }: BlockPreviewProps) {
|
|
|
20
20
|
<p className="text-sm font-medium text-foreground">
|
|
21
21
|
{heading || <span className="text-muted-foreground">CTA Heading</span>}
|
|
22
22
|
</p>
|
|
23
|
-
{body &&
|
|
24
|
-
<p className="mt-1 text-xs text-muted-foreground">{body}</p>
|
|
25
|
-
)}
|
|
23
|
+
{body && <p className="mt-1 text-xs text-muted-foreground">{body}</p>}
|
|
26
24
|
</div>
|
|
27
25
|
{button}
|
|
28
26
|
</div>
|
|
29
|
-
)
|
|
27
|
+
)
|
|
30
28
|
}
|
|
31
29
|
|
|
32
30
|
if (variant === 'floating') {
|
|
@@ -44,7 +42,7 @@ export function CTAPreview({ data, variant = 'banner' }: BlockPreviewProps) {
|
|
|
44
42
|
<div className="mt-4">{button}</div>
|
|
45
43
|
</div>
|
|
46
44
|
</div>
|
|
47
|
-
)
|
|
45
|
+
)
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
if (variant === 'split') {
|
|
@@ -62,7 +60,7 @@ export function CTAPreview({ data, variant = 'banner' }: BlockPreviewProps) {
|
|
|
62
60
|
</div>
|
|
63
61
|
<div className="shrink-0">{button}</div>
|
|
64
62
|
</div>
|
|
65
|
-
)
|
|
63
|
+
)
|
|
66
64
|
}
|
|
67
65
|
|
|
68
66
|
return (
|
|
@@ -77,5 +75,5 @@ export function CTAPreview({ data, variant = 'banner' }: BlockPreviewProps) {
|
|
|
77
75
|
)}
|
|
78
76
|
<div className="mt-4">{button}</div>
|
|
79
77
|
</div>
|
|
80
|
-
)
|
|
78
|
+
)
|
|
81
79
|
}
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
'use client'
|
|
1
|
+
'use client'
|
|
2
2
|
|
|
3
|
-
import { Image } from 'lucide-react'
|
|
4
|
-
import type { BlockPreviewProps } from './index.js'
|
|
3
|
+
import { Image } from 'lucide-react'
|
|
4
|
+
import type { BlockPreviewProps } from './index.js'
|
|
5
5
|
|
|
6
6
|
interface CardItem {
|
|
7
|
-
title?: string
|
|
8
|
-
description?: string
|
|
9
|
-
image?: string
|
|
10
|
-
link?: string
|
|
11
|
-
icon?: string
|
|
7
|
+
title?: string
|
|
8
|
+
description?: string
|
|
9
|
+
image?: string
|
|
10
|
+
link?: string
|
|
11
|
+
icon?: string
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export function CardsPreview({ data, variant = 'grid-3' }: BlockPreviewProps) {
|
|
15
|
-
const items = (data.items as CardItem[]) || []
|
|
15
|
+
const items = (data.items as CardItem[]) || []
|
|
16
16
|
|
|
17
17
|
const placeholderItems: CardItem[] =
|
|
18
18
|
items.length > 0
|
|
@@ -21,7 +21,7 @@ export function CardsPreview({ data, variant = 'grid-3' }: BlockPreviewProps) {
|
|
|
21
21
|
{ title: 'Card Title', description: 'Card description text' },
|
|
22
22
|
{ title: 'Card Title', description: 'Card description text' },
|
|
23
23
|
{ title: 'Card Title', description: 'Card description text' },
|
|
24
|
-
]
|
|
24
|
+
]
|
|
25
25
|
|
|
26
26
|
const gridClass =
|
|
27
27
|
variant === 'grid-2'
|
|
@@ -30,7 +30,7 @@ export function CardsPreview({ data, variant = 'grid-3' }: BlockPreviewProps) {
|
|
|
30
30
|
? 'grid grid-cols-4 gap-3'
|
|
31
31
|
: variant === 'horizontal'
|
|
32
32
|
? 'flex gap-3 overflow-hidden'
|
|
33
|
-
: 'grid grid-cols-3 gap-3'
|
|
33
|
+
: 'grid grid-cols-3 gap-3'
|
|
34
34
|
|
|
35
35
|
return (
|
|
36
36
|
<div className="rounded-md border border-border p-4">
|
|
@@ -53,9 +53,7 @@ export function CardsPreview({ data, variant = 'grid-3' }: BlockPreviewProps) {
|
|
|
53
53
|
</div>
|
|
54
54
|
<div className="p-3">
|
|
55
55
|
<p className="text-sm font-medium text-foreground">
|
|
56
|
-
{item.title ||
|
|
57
|
-
<span className="text-muted-foreground">Card Title</span>
|
|
58
|
-
)}
|
|
56
|
+
{item.title || <span className="text-muted-foreground">Card Title</span>}
|
|
59
57
|
</p>
|
|
60
58
|
{item.description && (
|
|
61
59
|
<p className="mt-1 text-xs text-muted-foreground line-clamp-2">
|
|
@@ -67,5 +65,5 @@ export function CardsPreview({ data, variant = 'grid-3' }: BlockPreviewProps) {
|
|
|
67
65
|
))}
|
|
68
66
|
</div>
|
|
69
67
|
</div>
|
|
70
|
-
)
|
|
68
|
+
)
|
|
71
69
|
}
|