@actuate-media/cms-admin 0.6.0 → 0.7.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 +17 -0
- package/dist/AdminRoot.js.map +1 -1
- package/dist/actuate-admin.css +1 -1
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/ErrorBoundary.js.map +1 -1
- package/dist/hooks/useBuilderState.d.ts +49 -0
- package/dist/hooks/useBuilderState.d.ts.map +1 -0
- package/dist/hooks/useBuilderState.js +238 -0
- package/dist/hooks/useBuilderState.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +2 -2
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/views/FormSubmissions.js +11 -11
- package/dist/views/FormSubmissions.js.map +1 -1
- package/dist/views/Forms.js +1 -1
- package/dist/views/Forms.js.map +1 -1
- package/dist/views/MediaBrowser.d.ts.map +1 -1
- package/dist/views/MediaBrowser.js +28 -8
- package/dist/views/MediaBrowser.js.map +1 -1
- package/dist/views/Posts.js +1 -1
- package/dist/views/Posts.js.map +1 -1
- package/dist/views/Redirects.js +2 -2
- package/dist/views/Redirects.js.map +1 -1
- package/dist/views/SEO.js +3 -3
- package/dist/views/SEO.js.map +1 -1
- package/dist/views/Users.js +3 -3
- package/dist/views/Users.js.map +1 -1
- package/dist/views/page-builder/AIBlockAssist.d.ts +9 -0
- package/dist/views/page-builder/AIBlockAssist.d.ts.map +1 -0
- package/dist/views/page-builder/AIBlockAssist.js +40 -0
- package/dist/views/page-builder/AIBlockAssist.js.map +1 -0
- package/dist/views/page-builder/AIGenerateDialog.d.ts +8 -0
- package/dist/views/page-builder/AIGenerateDialog.d.ts.map +1 -0
- package/dist/views/page-builder/AIGenerateDialog.js +170 -0
- package/dist/views/page-builder/AIGenerateDialog.js.map +1 -0
- package/dist/views/page-builder/BlockEditor.d.ts +11 -0
- package/dist/views/page-builder/BlockEditor.d.ts.map +1 -0
- package/dist/views/page-builder/BlockEditor.js +67 -0
- package/dist/views/page-builder/BlockEditor.js.map +1 -0
- package/dist/views/page-builder/BlockPicker.d.ts +7 -0
- package/dist/views/page-builder/BlockPicker.d.ts.map +1 -0
- package/dist/views/page-builder/BlockPicker.js +102 -0
- package/dist/views/page-builder/BlockPicker.js.map +1 -0
- package/dist/views/page-builder/BottomBar.d.ts +9 -0
- package/dist/views/page-builder/BottomBar.d.ts.map +1 -0
- package/dist/views/page-builder/BottomBar.js +13 -0
- package/dist/views/page-builder/BottomBar.js.map +1 -0
- package/dist/views/page-builder/BuilderToolbar.d.ts +21 -0
- package/dist/views/page-builder/BuilderToolbar.d.ts.map +1 -0
- package/dist/views/page-builder/BuilderToolbar.js +18 -0
- package/dist/views/page-builder/BuilderToolbar.js.map +1 -0
- package/dist/views/page-builder/ContextPanel.d.ts +20 -0
- package/dist/views/page-builder/ContextPanel.d.ts.map +1 -0
- package/dist/views/page-builder/ContextPanel.js +40 -0
- package/dist/views/page-builder/ContextPanel.js.map +1 -0
- package/dist/views/page-builder/DesignScore.d.ts +6 -0
- package/dist/views/page-builder/DesignScore.d.ts.map +1 -0
- package/dist/views/page-builder/DesignScore.js +93 -0
- package/dist/views/page-builder/DesignScore.js.map +1 -0
- package/dist/views/page-builder/NodeSettings.d.ts +12 -0
- package/dist/views/page-builder/NodeSettings.d.ts.map +1 -0
- package/dist/views/page-builder/NodeSettings.js +80 -0
- package/dist/views/page-builder/NodeSettings.js.map +1 -0
- package/dist/views/page-builder/PageBuilder.d.ts +8 -0
- package/dist/views/page-builder/PageBuilder.d.ts.map +1 -0
- package/dist/views/page-builder/PageBuilder.js +126 -0
- package/dist/views/page-builder/PageBuilder.js.map +1 -0
- package/dist/views/page-builder/PageSettings.d.ts +7 -0
- package/dist/views/page-builder/PageSettings.d.ts.map +1 -0
- package/dist/views/page-builder/PageSettings.js +27 -0
- package/dist/views/page-builder/PageSettings.js.map +1 -0
- package/dist/views/page-builder/PageTemplates.d.ts +5 -0
- package/dist/views/page-builder/PageTemplates.d.ts.map +1 -0
- package/dist/views/page-builder/PageTemplates.js +13 -0
- package/dist/views/page-builder/PageTemplates.js.map +1 -0
- package/dist/views/page-builder/SEOPanel.d.ts +10 -0
- package/dist/views/page-builder/SEOPanel.d.ts.map +1 -0
- package/dist/views/page-builder/SEOPanel.js +105 -0
- package/dist/views/page-builder/SEOPanel.js.map +1 -0
- package/dist/views/page-builder/SavedSections.d.ts +6 -0
- package/dist/views/page-builder/SavedSections.d.ts.map +1 -0
- package/dist/views/page-builder/SavedSections.js +145 -0
- package/dist/views/page-builder/SavedSections.js.map +1 -0
- package/dist/views/page-builder/TemplatePicker.d.ts +7 -0
- package/dist/views/page-builder/TemplatePicker.d.ts.map +1 -0
- package/dist/views/page-builder/TemplatePicker.js +68 -0
- package/dist/views/page-builder/TemplatePicker.js.map +1 -0
- package/dist/views/page-builder/block-renderers/CTAPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/CTAPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/CTAPreview.js +19 -0
- package/dist/views/page-builder/block-renderers/CTAPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/CardsPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/CardsPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/CardsPreview.js +22 -0
- package/dist/views/page-builder/block-renderers/CardsPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/CodePreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/CodePreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/CodePreview.js +16 -0
- package/dist/views/page-builder/block-renderers/CodePreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/FAQPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/FAQPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/FAQPreview.js +24 -0
- package/dist/views/page-builder/block-renderers/FAQPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts +6 -0
- package/dist/views/page-builder/block-renderers/FallbackPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/FallbackPreview.js +7 -0
- package/dist/views/page-builder/block-renderers/FallbackPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/FormPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/FormPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/FormPreview.js +14 -0
- package/dist/views/page-builder/block-renderers/FormPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/GalleryPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/GalleryPreview.js +21 -0
- package/dist/views/page-builder/block-renderers/GalleryPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/HeroPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/HeroPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/HeroPreview.js +19 -0
- package/dist/views/page-builder/block-renderers/HeroPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/ImagePreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/ImagePreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/ImagePreview.js +17 -0
- package/dist/views/page-builder/block-renderers/ImagePreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/TextPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/TextPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/TextPreview.js +26 -0
- package/dist/views/page-builder/block-renderers/TextPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/VideoPreview.d.ts +3 -0
- package/dist/views/page-builder/block-renderers/VideoPreview.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/VideoPreview.js +21 -0
- package/dist/views/page-builder/block-renderers/VideoPreview.js.map +1 -0
- package/dist/views/page-builder/block-renderers/index.d.ts +9 -0
- package/dist/views/page-builder/block-renderers/index.d.ts.map +1 -0
- package/dist/views/page-builder/block-renderers/index.js +25 -0
- package/dist/views/page-builder/block-renderers/index.js.map +1 -0
- package/dist/views/page-builder/canvas/BlockRenderer.d.ts +8 -0
- package/dist/views/page-builder/canvas/BlockRenderer.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/BlockRenderer.js +30 -0
- package/dist/views/page-builder/canvas/BlockRenderer.js.map +1 -0
- package/dist/views/page-builder/canvas/BuilderCanvas.d.ts +10 -0
- package/dist/views/page-builder/canvas/BuilderCanvas.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/BuilderCanvas.js +26 -0
- package/dist/views/page-builder/canvas/BuilderCanvas.js.map +1 -0
- package/dist/views/page-builder/canvas/ColumnRenderer.d.ts +8 -0
- package/dist/views/page-builder/canvas/ColumnRenderer.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/ColumnRenderer.js +36 -0
- package/dist/views/page-builder/canvas/ColumnRenderer.js.map +1 -0
- package/dist/views/page-builder/canvas/ContainerRenderer.d.ts +8 -0
- package/dist/views/page-builder/canvas/ContainerRenderer.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/ContainerRenderer.js +33 -0
- package/dist/views/page-builder/canvas/ContainerRenderer.js.map +1 -0
- package/dist/views/page-builder/canvas/RowRenderer.d.ts +8 -0
- package/dist/views/page-builder/canvas/RowRenderer.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/RowRenderer.js +32 -0
- package/dist/views/page-builder/canvas/RowRenderer.js.map +1 -0
- package/dist/views/page-builder/canvas/SectionRenderer.d.ts +8 -0
- package/dist/views/page-builder/canvas/SectionRenderer.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/SectionRenderer.js +54 -0
- package/dist/views/page-builder/canvas/SectionRenderer.js.map +1 -0
- package/dist/views/page-builder/canvas/index.d.ts +3 -0
- package/dist/views/page-builder/canvas/index.d.ts.map +1 -0
- package/dist/views/page-builder/canvas/index.js +2 -0
- package/dist/views/page-builder/canvas/index.js.map +1 -0
- package/package.json +3 -2
- package/src/AdminRoot.tsx +21 -0
- package/src/components/ErrorBoundary.tsx +3 -3
- package/src/hooks/useBuilderState.ts +328 -0
- package/src/index.ts +4 -0
- package/src/layout/Sidebar.tsx +5 -0
- package/src/views/FormSubmissions.tsx +12 -12
- package/src/views/Forms.tsx +1 -1
- package/src/views/MediaBrowser.tsx +46 -15
- package/src/views/Posts.tsx +1 -1
- package/src/views/Redirects.tsx +2 -2
- package/src/views/SEO.tsx +3 -3
- package/src/views/Users.tsx +3 -3
- package/src/views/page-builder/AIBlockAssist.tsx +68 -0
- package/src/views/page-builder/AIGenerateDialog.tsx +574 -0
- package/src/views/page-builder/BlockEditor.tsx +352 -0
- package/src/views/page-builder/BlockPicker.tsx +338 -0
- package/src/views/page-builder/BottomBar.tsx +64 -0
- package/src/views/page-builder/BuilderToolbar.tsx +218 -0
- package/src/views/page-builder/ContextPanel.tsx +145 -0
- package/src/views/page-builder/DesignScore.tsx +258 -0
- package/src/views/page-builder/NodeSettings.tsx +515 -0
- package/src/views/page-builder/PageBuilder.tsx +288 -0
- package/src/views/page-builder/PageSettings.tsx +161 -0
- package/src/views/page-builder/PageTemplates.tsx +105 -0
- package/src/views/page-builder/SEOPanel.tsx +485 -0
- package/src/views/page-builder/SavedSections.tsx +486 -0
- package/src/views/page-builder/TemplatePicker.tsx +201 -0
- package/src/views/page-builder/block-renderers/CTAPreview.tsx +81 -0
- package/src/views/page-builder/block-renderers/CardsPreview.tsx +71 -0
- package/src/views/page-builder/block-renderers/CodePreview.tsx +46 -0
- package/src/views/page-builder/block-renderers/FAQPreview.tsx +90 -0
- package/src/views/page-builder/block-renderers/FallbackPreview.tsx +18 -0
- package/src/views/page-builder/block-renderers/FormPreview.tsx +69 -0
- package/src/views/page-builder/block-renderers/GalleryPreview.tsx +93 -0
- package/src/views/page-builder/block-renderers/HeroPreview.tsx +103 -0
- package/src/views/page-builder/block-renderers/ImagePreview.tsx +54 -0
- package/src/views/page-builder/block-renderers/TextPreview.tsx +81 -0
- package/src/views/page-builder/block-renderers/VideoPreview.tsx +78 -0
- package/src/views/page-builder/block-renderers/index.ts +34 -0
- package/src/views/page-builder/canvas/BlockRenderer.tsx +62 -0
- package/src/views/page-builder/canvas/BuilderCanvas.tsx +90 -0
- package/src/views/page-builder/canvas/ColumnRenderer.tsx +86 -0
- package/src/views/page-builder/canvas/ContainerRenderer.tsx +71 -0
- package/src/views/page-builder/canvas/RowRenderer.tsx +72 -0
- package/src/views/page-builder/canvas/SectionRenderer.tsx +97 -0
- package/src/views/page-builder/canvas/index.ts +2 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronLeft, Undo2, Redo2, Monitor, Tablet, Smartphone, Loader2, Sparkles, } from 'lucide-react';
|
|
4
|
+
const STATUS_STYLES = {
|
|
5
|
+
DRAFT: 'bg-muted text-muted-foreground',
|
|
6
|
+
PUBLISHED: 'bg-primary/10 text-primary',
|
|
7
|
+
SCHEDULED: 'bg-accent text-accent-foreground',
|
|
8
|
+
};
|
|
9
|
+
export function BuilderToolbar({ collectionSlug, pageSettings, status, dirty, saving, canUndo, canRedo, deviceMode, onNavigate, onTitleChange, onUndo, onRedo, onDeviceMode, onSave, onPublish, onOpenAI, }) {
|
|
10
|
+
const collectionLabel = collectionSlug.charAt(0).toUpperCase() + collectionSlug.slice(1);
|
|
11
|
+
return (_jsxs("div", { className: "h-14 bg-card border-b border-border flex items-center px-4 gap-3 shrink-0", role: "toolbar", "aria-label": "Page builder toolbar", children: [_jsxs("button", { onClick: () => onNavigate(`/collections/${collectionSlug}`), className: "flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground transition-colors", "aria-label": `Back to ${collectionLabel}`, children: [_jsx(ChevronLeft, { size: 16 }), _jsx("span", { className: "hidden sm:inline", children: collectionLabel })] }), _jsx("div", { className: "w-px h-6 bg-border" }), _jsx("input", { type: "text", value: pageSettings.title, onChange: (e) => onTitleChange(e.target.value), placeholder: "Untitled Page", className: "flex-1 min-w-0 text-sm font-medium text-foreground bg-transparent border-none outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 rounded-sm placeholder:text-muted-foreground", "aria-label": "Page title" }), _jsx("span", { className: `text-xs font-medium px-2 py-0.5 rounded-md whitespace-nowrap ${STATUS_STYLES[status] ?? STATUS_STYLES.DRAFT}`, children: status }), dirty && !saving && (_jsx("span", { className: "w-2 h-2 rounded-full bg-destructive shrink-0", title: "Unsaved changes", "aria-label": "Unsaved changes" })), _jsx("div", { className: "w-px h-6 bg-border" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: onUndo, disabled: !canUndo, className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted disabled:opacity-30 disabled:pointer-events-none transition-colors", "aria-label": "Undo", children: _jsx(Undo2, { size: 16 }) }), _jsx("button", { onClick: onRedo, disabled: !canRedo, className: "p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted disabled:opacity-30 disabled:pointer-events-none transition-colors", "aria-label": "Redo", children: _jsx(Redo2, { size: 16 }) })] }), _jsx("div", { className: "w-px h-6 bg-border" }), _jsxs("div", { className: "flex items-center gap-0.5 bg-muted rounded-md p-0.5", children: [_jsx(DeviceButton, { active: deviceMode === 'desktop', onClick: () => onDeviceMode('desktop'), label: "Desktop view", children: _jsx(Monitor, { size: 16 }) }), _jsx(DeviceButton, { active: deviceMode === 'tablet', onClick: () => onDeviceMode('tablet'), label: "Tablet view", children: _jsx(Tablet, { size: 16 }) }), _jsx(DeviceButton, { active: deviceMode === 'mobile', onClick: () => onDeviceMode('mobile'), label: "Mobile view", children: _jsx(Smartphone, { size: 16 }) })] }), _jsx("div", { className: "w-px h-6 bg-border" }), onOpenAI && (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: onOpenAI, className: "flex items-center gap-1.5 px-2.5 py-1.5 text-sm font-medium text-primary bg-primary/10 rounded-md hover:bg-primary/20 transition-colors", "aria-label": "Generate page with AI", children: [_jsx(Sparkles, { size: 14 }), _jsx("span", { className: "hidden sm:inline", children: "AI" })] }), _jsx("div", { className: "w-px h-6 bg-border" })] })), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { onClick: onSave, disabled: saving || !dirty, className: "bg-muted text-muted-foreground rounded-md px-3 py-1.5 text-sm font-medium hover:bg-muted/80 disabled:opacity-50 disabled:pointer-events-none transition-colors flex items-center gap-1.5", children: [saving && _jsx(Loader2, { size: 14, className: "animate-spin" }), saving ? 'Saving...' : 'Save'] }), _jsx("button", { onClick: onPublish, disabled: saving, className: "bg-primary text-primary-foreground rounded-md px-3 py-1.5 text-sm font-medium hover:bg-primary/90 disabled:opacity-50 disabled:pointer-events-none transition-colors", children: "Publish" })] })] }));
|
|
12
|
+
}
|
|
13
|
+
function DeviceButton({ active, onClick, label, children, }) {
|
|
14
|
+
return (_jsx("button", { onClick: onClick, className: `p-1.5 rounded-md transition-colors ${active
|
|
15
|
+
? 'bg-background text-foreground shadow-sm'
|
|
16
|
+
: 'text-muted-foreground hover:text-foreground'}`, "aria-label": label, "aria-pressed": active, children: children }));
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=BuilderToolbar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuilderToolbar.js","sourceRoot":"","sources":["../../../src/views/page-builder/BuilderToolbar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BuilderNode, PageNode } from '@actuate-media/cms-core';
|
|
2
|
+
import type { PageSettings } from '../../hooks/useBuilderState.js';
|
|
3
|
+
export interface ContextPanelProps {
|
|
4
|
+
activeTab: 'block' | 'node' | 'page' | 'seo' | 'design';
|
|
5
|
+
onTabChange: (tab: 'block' | 'node' | 'page' | 'seo' | 'design') => void;
|
|
6
|
+
selectedNode: BuilderNode | null;
|
|
7
|
+
tree: PageNode;
|
|
8
|
+
pageSettings: PageSettings;
|
|
9
|
+
onUpdateSettings: (id: string, settings: Record<string, unknown>) => void;
|
|
10
|
+
onUpdateBlock: (id: string, data: Record<string, unknown>) => void;
|
|
11
|
+
onRemoveNode: (id: string) => void;
|
|
12
|
+
onDuplicateNode: (id: string) => void;
|
|
13
|
+
onMoveNodeUp: (id: string) => void;
|
|
14
|
+
onMoveNodeDown: (id: string) => void;
|
|
15
|
+
onPageSettingsChange: (settings: Partial<PageSettings>) => void;
|
|
16
|
+
onAddRow: (sectionId: string) => void;
|
|
17
|
+
config: any;
|
|
18
|
+
}
|
|
19
|
+
export declare function ContextPanel({ activeTab, onTabChange, selectedNode, tree, pageSettings, onUpdateSettings, onUpdateBlock, onRemoveNode, onDuplicateNode, onMoveNodeUp, onMoveNodeDown, onPageSettingsChange, onAddRow, config, }: ContextPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=ContextPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextPanel.d.ts","sourceRoot":"","sources":["../../../src/views/page-builder/ContextPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAMrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IACxD,WAAW,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,KAAK,IAAI,CAAC;IACzE,YAAY,EAAE,WAAW,GAAG,IAAI,CAAC;IACjC,IAAI,EAAE,QAAQ,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC1E,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IACnE,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,oBAAoB,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IAChE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,MAAM,EAAE,GAAG,CAAC;CACb;AAgBD,wBAAgB,YAAY,CAAC,EAC3B,SAAS,EACT,WAAW,EACX,YAAY,EACZ,IAAI,EACJ,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,oBAAoB,EACpB,QAAQ,EACR,MAAM,GACP,EAAE,iBAAiB,2CAqFnB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import * as Tabs from '@radix-ui/react-tabs';
|
|
5
|
+
import { Blocks, Settings2, FileText, Search, Palette } from 'lucide-react';
|
|
6
|
+
import { BlockEditor } from './BlockEditor.js';
|
|
7
|
+
import { NodeSettings } from './NodeSettings.js';
|
|
8
|
+
import { PageSettingsEditor } from './PageSettings.js';
|
|
9
|
+
import { BuilderSEOPanel } from './SEOPanel.js';
|
|
10
|
+
import { DesignScorePanel } from './DesignScore.js';
|
|
11
|
+
const TABS = [
|
|
12
|
+
{ value: 'block', label: 'Block', icon: Blocks },
|
|
13
|
+
{ value: 'node', label: 'Node', icon: Settings2 },
|
|
14
|
+
{ value: 'page', label: 'Page', icon: FileText },
|
|
15
|
+
{ value: 'seo', label: 'SEO', icon: Search },
|
|
16
|
+
{ value: 'design', label: 'Design', icon: Palette },
|
|
17
|
+
];
|
|
18
|
+
export function ContextPanel({ activeTab, onTabChange, selectedNode, tree, pageSettings, onUpdateSettings, onUpdateBlock, onRemoveNode, onDuplicateNode, onMoveNodeUp, onMoveNodeDown, onPageSettingsChange, onAddRow, config, }) {
|
|
19
|
+
const availableTabs = useMemo(() => {
|
|
20
|
+
if (!selectedNode)
|
|
21
|
+
return TABS.filter((t) => t.value !== 'block' && t.value !== 'node');
|
|
22
|
+
if (selectedNode.type === 'block')
|
|
23
|
+
return TABS.filter((t) => t.value !== 'node');
|
|
24
|
+
return TABS.filter((t) => t.value !== 'block');
|
|
25
|
+
}, [selectedNode]);
|
|
26
|
+
const effectiveTab = useMemo(() => {
|
|
27
|
+
if (availableTabs.some((t) => t.value === activeTab))
|
|
28
|
+
return activeTab;
|
|
29
|
+
if (selectedNode?.type === 'block')
|
|
30
|
+
return 'block';
|
|
31
|
+
if (selectedNode)
|
|
32
|
+
return 'node';
|
|
33
|
+
return 'page';
|
|
34
|
+
}, [activeTab, availableTabs, selectedNode]);
|
|
35
|
+
return (_jsx("div", { className: "w-full h-full bg-card overflow-y-auto", children: _jsxs(Tabs.Root, { value: effectiveTab, onValueChange: (value) => onTabChange(value), children: [_jsx(Tabs.List, { className: "flex border-b border-border bg-muted/30", children: availableTabs.map((tab) => {
|
|
36
|
+
const Icon = tab.icon;
|
|
37
|
+
return (_jsxs(Tabs.Trigger, { value: tab.value, className: "flex-1 flex items-center justify-center gap-1.5 px-2 py-2.5 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground data-[state=active]:text-foreground data-[state=active]:border-b-2 data-[state=active]:border-primary data-[state=active]:bg-background", children: [_jsx(Icon, { size: 14 }), _jsx("span", { children: tab.label })] }, tab.value));
|
|
38
|
+
}) }), _jsx(Tabs.Content, { value: "block", children: selectedNode?.type === 'block' && (_jsx(BlockEditor, { node: selectedNode, onUpdateBlock: onUpdateBlock, onUpdateSettings: onUpdateSettings, onRemoveNode: onRemoveNode, onDuplicateNode: onDuplicateNode, config: config })) }), _jsx(Tabs.Content, { value: "node", children: selectedNode && selectedNode.type !== 'block' && selectedNode.type !== 'page' && selectedNode.type !== 'savedSectionRef' && (_jsx(NodeSettings, { node: selectedNode, onUpdateSettings: onUpdateSettings, onRemoveNode: onRemoveNode, onDuplicateNode: onDuplicateNode, onMoveNodeUp: onMoveNodeUp, onMoveNodeDown: onMoveNodeDown, onAddRow: selectedNode.type === 'section' ? onAddRow : undefined })) }), _jsx(Tabs.Content, { value: "page", children: _jsx(PageSettingsEditor, { settings: pageSettings, onChange: onPageSettingsChange }) }), _jsx(Tabs.Content, { value: "seo", children: _jsx(BuilderSEOPanel, { tree: tree, pageSettings: pageSettings, onPageSettingsChange: onPageSettingsChange, selectedNodeId: selectedNode?.id ?? null }) }), _jsx(Tabs.Content, { value: "design", children: _jsx(DesignScorePanel, { tree: tree }) })] }) }));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=ContextPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextPanel.js","sourceRoot":"","sources":["../../../src/views/page-builder/ContextPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PageNode } from '@actuate-media/cms-core';
|
|
2
|
+
export interface DesignScorePanelProps {
|
|
3
|
+
tree: PageNode;
|
|
4
|
+
}
|
|
5
|
+
export declare function DesignScorePanel({ tree }: DesignScorePanelProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
//# sourceMappingURL=DesignScore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesignScore.d.ts","sourceRoot":"","sources":["../../../src/views/page-builder/DesignScore.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,QAAQ,EAKT,MAAM,yBAAyB,CAAC;AAWjC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,QAAQ,CAAC;CAChB;AAgMD,wBAAgB,gBAAgB,CAAC,EAAE,IAAI,EAAE,EAAE,qBAAqB,2CA0C/D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useMemo } from 'react';
|
|
4
|
+
import { analyzeDesign } from '@actuate-media/cms-core';
|
|
5
|
+
import { CheckCircle2, AlertCircle, XCircle, ChevronDown, ChevronUp, Lightbulb, Palette, } from 'lucide-react';
|
|
6
|
+
function getScoreColor(score, max) {
|
|
7
|
+
const ratio = max > 0 ? score / max : 0;
|
|
8
|
+
if (ratio >= 0.8)
|
|
9
|
+
return 'text-green-500';
|
|
10
|
+
if (ratio >= 0.5)
|
|
11
|
+
return 'text-amber-500';
|
|
12
|
+
return 'text-red-500';
|
|
13
|
+
}
|
|
14
|
+
function getBarColor(score, max) {
|
|
15
|
+
const ratio = max > 0 ? score / max : 0;
|
|
16
|
+
if (ratio >= 0.8)
|
|
17
|
+
return 'bg-green-500';
|
|
18
|
+
if (ratio >= 0.5)
|
|
19
|
+
return 'bg-amber-500';
|
|
20
|
+
return 'bg-red-500';
|
|
21
|
+
}
|
|
22
|
+
function getScoreLabel(score) {
|
|
23
|
+
if (score >= 80)
|
|
24
|
+
return 'Excellent';
|
|
25
|
+
if (score >= 65)
|
|
26
|
+
return 'Good';
|
|
27
|
+
if (score >= 50)
|
|
28
|
+
return 'Needs Work';
|
|
29
|
+
return 'Poor';
|
|
30
|
+
}
|
|
31
|
+
function getRingStrokeColor(score) {
|
|
32
|
+
if (score >= 80)
|
|
33
|
+
return 'rgb(34, 197, 94)';
|
|
34
|
+
if (score >= 50)
|
|
35
|
+
return 'rgb(245, 158, 11)';
|
|
36
|
+
return 'rgb(239, 68, 68)';
|
|
37
|
+
}
|
|
38
|
+
function StatusIcon({ status }) {
|
|
39
|
+
switch (status) {
|
|
40
|
+
case 'good':
|
|
41
|
+
return _jsx(CheckCircle2, { size: 14, className: "text-green-500 shrink-0" });
|
|
42
|
+
case 'warning':
|
|
43
|
+
return _jsx(AlertCircle, { size: 14, className: "text-amber-500 shrink-0" });
|
|
44
|
+
case 'error':
|
|
45
|
+
return _jsx(XCircle, { size: 14, className: "text-red-500 shrink-0" });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function SeverityBadge({ severity }) {
|
|
49
|
+
const classes = {
|
|
50
|
+
important: 'bg-red-100 text-red-700',
|
|
51
|
+
suggestion: 'bg-amber-100 text-amber-700',
|
|
52
|
+
info: 'bg-blue-100 text-blue-700',
|
|
53
|
+
};
|
|
54
|
+
return (_jsx("span", { className: `inline-block px-1.5 py-0.5 rounded text-xs font-medium ${classes[severity]}`, children: severity }));
|
|
55
|
+
}
|
|
56
|
+
function ScoreRing({ score }) {
|
|
57
|
+
const radius = 32;
|
|
58
|
+
const strokeWidth = 6;
|
|
59
|
+
const circumference = 2 * Math.PI * radius;
|
|
60
|
+
const progress = Math.min(score, 100) / 100;
|
|
61
|
+
const dashOffset = circumference * (1 - progress);
|
|
62
|
+
const size = (radius + strokeWidth) * 2;
|
|
63
|
+
return (_jsxs("div", { className: "flex flex-col items-center gap-2", children: [_jsxs("div", { className: "relative", children: [_jsxs("svg", { width: size, height: size, viewBox: `0 0 ${size} ${size}`, className: "-rotate-90", children: [_jsx("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: "var(--border)", strokeWidth: strokeWidth }), _jsx("circle", { cx: size / 2, cy: size / 2, r: radius, fill: "none", stroke: getRingStrokeColor(score), strokeWidth: strokeWidth, strokeDasharray: circumference, strokeDashoffset: dashOffset, strokeLinecap: "round", className: "transition-all duration-700 ease-out" })] }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("span", { className: `text-lg font-medium ${getScoreColor(score, 100)}`, children: score }) })] }), _jsx("span", { className: "text-xs text-muted-foreground", children: getScoreLabel(score) })] }));
|
|
64
|
+
}
|
|
65
|
+
function CategoryRow({ category, expanded, onToggle, }) {
|
|
66
|
+
const percentage = category.maxScore > 0 ? (category.score / category.maxScore) * 100 : 0;
|
|
67
|
+
return (_jsxs("div", { className: "border-b border-border last:border-b-0", children: [_jsxs("button", { type: "button", className: "w-full text-left px-4 py-3 flex flex-col gap-2 hover:bg-muted/50 transition-colors", onClick: onToggle, "aria-expanded": expanded, children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: category.label }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-xs text-muted-foreground", children: [category.score, "/", category.maxScore] }), expanded ? (_jsx(ChevronUp, { size: 14, className: "text-muted-foreground" })) : (_jsx(ChevronDown, { size: 14, className: "text-muted-foreground" }))] })] }), _jsx("div", { className: "w-full h-1.5 rounded-full bg-muted overflow-hidden", children: _jsx("div", { className: `h-full rounded-full transition-all duration-500 ease-out ${getBarColor(category.score, category.maxScore)}`, style: { width: `${percentage}%` } }) })] }), expanded && category.checks.length > 0 && (_jsx("div", { className: "px-4 pb-3 flex flex-col gap-2", children: category.checks.map((check) => (_jsxs("div", { className: "flex items-start gap-2 pl-1", children: [_jsx(StatusIcon, { status: check.status }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-xs font-medium text-foreground", children: check.label }), _jsx("span", { className: "text-xs text-muted-foreground", children: check.detail })] })] }, check.id))) }))] }));
|
|
68
|
+
}
|
|
69
|
+
function SuggestionsList({ suggestions }) {
|
|
70
|
+
const sorted = useMemo(() => {
|
|
71
|
+
const order = {
|
|
72
|
+
important: 0,
|
|
73
|
+
suggestion: 1,
|
|
74
|
+
info: 2,
|
|
75
|
+
};
|
|
76
|
+
return [...suggestions].sort((a, b) => order[a.severity] - order[b.severity]);
|
|
77
|
+
}, [suggestions]);
|
|
78
|
+
if (sorted.length === 0)
|
|
79
|
+
return null;
|
|
80
|
+
return (_jsxs("div", { className: "px-4 py-3 border-t border-border", children: [_jsxs("div", { className: "flex items-center gap-2 mb-3", children: [_jsx(Lightbulb, { size: 14, className: "text-muted-foreground" }), _jsx("span", { className: "text-xs font-medium text-foreground", children: "Suggestions" })] }), _jsx("div", { className: "flex flex-col gap-2.5", children: sorted.map((suggestion) => (_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(SeverityBadge, { severity: suggestion.severity }), _jsx("span", { className: "text-xs text-muted-foreground leading-relaxed", children: suggestion.message })] }, suggestion.id))) })] }));
|
|
81
|
+
}
|
|
82
|
+
export function DesignScorePanel({ tree }) {
|
|
83
|
+
const analysis = useMemo(() => analyzeDesign(tree), [tree]);
|
|
84
|
+
const [expandedCategories, setExpandedCategories] = useState([]);
|
|
85
|
+
const toggleCategory = (name) => {
|
|
86
|
+
setExpandedCategories((prev) => prev.includes(name) ? prev.filter((n) => n !== name) : [...prev, name]);
|
|
87
|
+
};
|
|
88
|
+
if (!tree.children || tree.children.length === 0) {
|
|
89
|
+
return (_jsxs("div", { className: "p-6 flex flex-col items-center justify-center text-center min-h-[200px]", children: [_jsx(Palette, { size: 32, className: "text-muted-foreground mb-3" }), _jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: "Design Score" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "Add sections to your page to see the design analysis" })] }));
|
|
90
|
+
}
|
|
91
|
+
return (_jsxs("div", { className: "flex flex-col", children: [_jsx("div", { className: "flex flex-col items-center py-5 border-b border-border", children: _jsx(ScoreRing, { score: analysis.score }) }), _jsx("div", { className: "flex flex-col", children: analysis.categories.map((category) => (_jsx(CategoryRow, { category: category, expanded: expandedCategories.includes(category.name), onToggle: () => toggleCategory(category.name) }, category.name))) }), _jsx(SuggestionsList, { suggestions: analysis.suggestions })] }));
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=DesignScore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesignScore.js","sourceRoot":"","sources":["../../../src/views/page-builder/DesignScore.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SectionNode, ContainerNode, RowNode, ColumnNode } from '@actuate-media/cms-core';
|
|
2
|
+
export interface NodeSettingsProps {
|
|
3
|
+
node: SectionNode | ContainerNode | RowNode | ColumnNode;
|
|
4
|
+
onUpdateSettings: (id: string, settings: Record<string, unknown>) => void;
|
|
5
|
+
onRemoveNode: (id: string) => void;
|
|
6
|
+
onDuplicateNode: (id: string) => void;
|
|
7
|
+
onMoveNodeUp: (id: string) => void;
|
|
8
|
+
onMoveNodeDown: (id: string) => void;
|
|
9
|
+
onAddRow?: (sectionId: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function NodeSettings({ node, onUpdateSettings, onRemoveNode, onDuplicateNode, onMoveNodeUp, onMoveNodeDown, onAddRow, }: NodeSettingsProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=NodeSettings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeSettings.d.ts","sourceRoot":"","sources":["../../../src/views/page-builder/NodeSettings.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAEV,WAAW,EACX,aAAa,EACb,OAAO,EACP,UAAU,EACX,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,CAAC;IACzD,gBAAgB,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC1E,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,eAAe,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,cAAc,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAiBD,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,gBAAgB,EAChB,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,cAAc,EACd,QAAQ,GACT,EAAE,iBAAiB,2CAyFnB"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from 'react';
|
|
4
|
+
import { ArrowUp, ArrowDown, Copy, Trash2, Plus, AlignLeft, AlignCenter, AlignRight, ArrowUpFromLine, ArrowDownToLine, Minus, } from 'lucide-react';
|
|
5
|
+
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
6
|
+
const INPUT_CLASS = 'w-full px-3 py-2 text-sm bg-background border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring';
|
|
7
|
+
const LABEL_CLASS = 'text-sm font-medium text-foreground mb-1 block';
|
|
8
|
+
const SECTION_HEADING_CLASS = 'text-xs font-medium uppercase tracking-wider text-muted-foreground mb-2';
|
|
9
|
+
const COLUMN_PRESETS = [
|
|
10
|
+
{ label: '12', widths: [12] },
|
|
11
|
+
{ label: '6 | 6', widths: [6, 6] },
|
|
12
|
+
{ label: '4 | 4 | 4', widths: [4, 4, 4] },
|
|
13
|
+
{ label: '3 | 3 | 3 | 3', widths: [3, 3, 3, 3] },
|
|
14
|
+
{ label: '8 | 4', widths: [8, 4] },
|
|
15
|
+
{ label: '4 | 8', widths: [4, 8] },
|
|
16
|
+
{ label: '3 | 6 | 3', widths: [3, 6, 3] },
|
|
17
|
+
];
|
|
18
|
+
export function NodeSettings({ node, onUpdateSettings, onRemoveNode, onDuplicateNode, onMoveNodeUp, onMoveNodeDown, onAddRow, }) {
|
|
19
|
+
const [confirmDelete, setConfirmDelete] = useState(false);
|
|
20
|
+
const updateSetting = useCallback((key, value) => {
|
|
21
|
+
onUpdateSettings(node.id, { [key]: value });
|
|
22
|
+
}, [node.id, onUpdateSettings]);
|
|
23
|
+
const handleDelete = useCallback(() => {
|
|
24
|
+
if (confirmDelete) {
|
|
25
|
+
onRemoveNode(node.id);
|
|
26
|
+
setConfirmDelete(false);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
setConfirmDelete(true);
|
|
30
|
+
}
|
|
31
|
+
}, [confirmDelete, node.id, onRemoveNode]);
|
|
32
|
+
const nodeLabel = node.type === 'section'
|
|
33
|
+
? 'Section'
|
|
34
|
+
: node.type === 'container'
|
|
35
|
+
? 'Container'
|
|
36
|
+
: node.type === 'row'
|
|
37
|
+
? 'Row'
|
|
38
|
+
: 'Column';
|
|
39
|
+
return (_jsxs("div", { className: "flex flex-col h-full", children: [_jsx("div", { className: "p-4 border-b border-border", children: _jsxs("p", { className: "text-sm font-medium text-foreground", children: [nodeLabel, " Settings"] }) }), _jsx("div", { className: "flex-1 overflow-y-auto", children: _jsxs("div", { className: "space-y-4 p-4", children: [node.type === 'section' && _jsx(SectionFields, { node: node, updateSetting: updateSetting, onAddRow: onAddRow }), node.type === 'container' && _jsx(ContainerFields, { node: node, updateSetting: updateSetting }), node.type === 'row' && _jsx(RowFields, { node: node, updateSetting: updateSetting }), node.type === 'column' && _jsx(ColumnFields, { node: node, updateSetting: updateSetting })] }) }), _jsxs("div", { className: "p-4 border-t border-border space-y-2", children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "Actions" }), _jsxs("div", { className: "flex gap-2", children: [_jsxs("button", { type: "button", onClick: () => onMoveNodeUp(node.id), "aria-label": "Move up", className: "flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm bg-background border border-input rounded-md hover:bg-accent transition-colors", children: [_jsx(ArrowUp, { size: 14 }), "Up"] }), _jsxs("button", { type: "button", onClick: () => onMoveNodeDown(node.id), "aria-label": "Move down", className: "flex-1 flex items-center justify-center gap-1.5 px-3 py-2 text-sm bg-background border border-input rounded-md hover:bg-accent transition-colors", children: [_jsx(ArrowDown, { size: 14 }), "Down"] })] }), _jsxs("button", { type: "button", onClick: () => onDuplicateNode(node.id), className: "w-full flex items-center justify-center gap-2 px-3 py-2 text-sm font-medium bg-background border border-input rounded-md hover:bg-accent transition-colors", children: [_jsx(Copy, { size: 14 }), "Duplicate"] }), _jsxs("button", { type: "button", onClick: handleDelete, onBlur: () => setConfirmDelete(false), className: `w-full flex items-center justify-center gap-2 px-3 py-2 text-sm font-medium rounded-md transition-colors ${confirmDelete
|
|
40
|
+
? 'bg-destructive text-destructive-foreground'
|
|
41
|
+
: 'bg-background border border-destructive text-destructive hover:bg-destructive/10'}`, children: [_jsx(Trash2, { size: 14 }), confirmDelete ? 'Click again to confirm' : 'Delete'] })] })] }));
|
|
42
|
+
}
|
|
43
|
+
function SectionFields({ node, updateSetting, onAddRow, }) {
|
|
44
|
+
const s = node.settings;
|
|
45
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "Background" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Background Color" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "color", value: s.background ?? '#ffffff', onChange: (e) => updateSetting('background', e.target.value), className: "h-9 w-9 rounded-md border border-input cursor-pointer" }), _jsx("input", { type: "text", value: s.background ?? '', onChange: (e) => updateSetting('background', e.target.value), placeholder: "transparent", className: `${INPUT_CLASS} flex-1` })] })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "Spacing" }), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Padding Top" }), _jsx("input", { type: "text", value: s.paddingTop ?? '', onChange: (e) => updateSetting('paddingTop', e.target.value), placeholder: "0px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Padding Bottom" }), _jsx("input", { type: "text", value: s.paddingBottom ?? '', onChange: (e) => updateSetting('paddingBottom', e.target.value), placeholder: "0px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Margin Top" }), _jsx("input", { type: "text", value: s.marginTop ?? '', onChange: (e) => updateSetting('marginTop', e.target.value), placeholder: "0px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Margin Bottom" }), _jsx("input", { type: "text", value: s.marginBottom ?? '', onChange: (e) => updateSetting('marginBottom', e.target.value), placeholder: "0px", className: INPUT_CLASS })] })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "Attributes" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { className: "text-sm font-medium text-foreground", children: "Visibility" }), _jsx(SwitchPrimitive.Root, { checked: s.visibility !== 'hidden', onCheckedChange: (checked) => updateSetting('visibility', checked ? 'visible' : 'hidden'), className: "w-9 h-5 bg-input rounded-full relative data-[state=checked]:bg-primary transition-colors", "aria-label": "Section visibility", children: _jsx(SwitchPrimitive.Thumb, { className: "block h-3.5 w-3.5 rounded-full bg-background shadow-sm transition-transform translate-x-0.5 data-[state=checked]:translate-x-[18px]" }) })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "HTML ID" }), _jsx("input", { type: "text", value: s.htmlId ?? '', onChange: (e) => updateSetting('htmlId', e.target.value), placeholder: "section-id", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "HTML Class" }), _jsx("input", { type: "text", value: s.htmlClass ?? '', onChange: (e) => updateSetting('htmlClass', e.target.value), placeholder: "my-class", className: INPUT_CLASS })] }), onAddRow && (_jsxs("button", { type: "button", onClick: () => onAddRow(node.id), className: "w-full flex items-center justify-center gap-2 px-3 py-2 text-sm font-medium bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors", children: [_jsx(Plus, { size: 14 }), "Add Row"] }))] }));
|
|
46
|
+
}
|
|
47
|
+
function ContainerFields({ node, updateSetting, }) {
|
|
48
|
+
const s = node.settings;
|
|
49
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "Layout" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Max Width" }), _jsx("input", { type: "text", value: s.maxWidth ?? '', onChange: (e) => updateSetting('maxWidth', e.target.value), placeholder: "1200px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Alignment" }), _jsx("div", { className: "flex gap-1", children: ['left', 'center', 'right'].map((align) => {
|
|
50
|
+
const Icon = align === 'left' ? AlignLeft : align === 'center' ? AlignCenter : AlignRight;
|
|
51
|
+
return (_jsx("button", { type: "button", onClick: () => updateSetting('alignment', align), "aria-label": `Align ${align}`, className: `flex-1 flex items-center justify-center py-2 rounded-md border transition-colors ${s.alignment === align
|
|
52
|
+
? 'bg-primary text-primary-foreground border-primary'
|
|
53
|
+
: 'bg-background border-input hover:bg-accent'}`, children: _jsx(Icon, { size: 14 }) }, align));
|
|
54
|
+
}) })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Padding" }), _jsx("input", { type: "text", value: s.padding ?? '', onChange: (e) => updateSetting('padding', e.target.value), placeholder: "0px", className: INPUT_CLASS })] })] }));
|
|
55
|
+
}
|
|
56
|
+
function RowFields({ node, updateSetting, }) {
|
|
57
|
+
const s = node.settings;
|
|
58
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "Layout" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Gap" }), _jsx("input", { type: "text", value: s.gap ?? '', onChange: (e) => updateSetting('gap', e.target.value), placeholder: "16px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Vertical Align" }), _jsx("div", { className: "flex gap-1", children: ['top', 'center', 'bottom', 'stretch'].map((align) => {
|
|
59
|
+
const Icon = align === 'top'
|
|
60
|
+
? ArrowUpFromLine
|
|
61
|
+
: align === 'bottom'
|
|
62
|
+
? ArrowDownToLine
|
|
63
|
+
: align === 'center'
|
|
64
|
+
? Minus
|
|
65
|
+
: AlignCenter;
|
|
66
|
+
return (_jsx("button", { type: "button", onClick: () => updateSetting('verticalAlign', align), "aria-label": `Align ${align}`, className: `flex-1 flex items-center justify-center py-2 rounded-md border text-xs transition-colors ${s.verticalAlign === align
|
|
67
|
+
? 'bg-primary text-primary-foreground border-primary'
|
|
68
|
+
: 'bg-background border-input hover:bg-accent'}`, children: _jsx(Icon, { size: 14 }) }, align));
|
|
69
|
+
}) })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "Mobile" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { className: "text-sm font-medium text-foreground", children: "Reverse on Mobile" }), _jsx(SwitchPrimitive.Root, { checked: !!s.reverseOnMobile, onCheckedChange: (checked) => updateSetting('reverseOnMobile', checked), className: "w-9 h-5 bg-input rounded-full relative data-[state=checked]:bg-primary transition-colors", "aria-label": "Reverse column order on mobile", children: _jsx(SwitchPrimitive.Thumb, { className: "block h-3.5 w-3.5 rounded-full bg-background shadow-sm transition-transform translate-x-0.5 data-[state=checked]:translate-x-[18px]" }) })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { className: "text-sm font-medium text-foreground", children: "Wrap on Mobile" }), _jsx(SwitchPrimitive.Root, { checked: !!s.wrapOnMobile, onCheckedChange: (checked) => updateSetting('wrapOnMobile', checked), className: "w-9 h-5 bg-input rounded-full relative data-[state=checked]:bg-primary transition-colors", "aria-label": "Wrap columns on mobile", children: _jsx(SwitchPrimitive.Thumb, { className: "block h-3.5 w-3.5 rounded-full bg-background shadow-sm transition-transform translate-x-0.5 data-[state=checked]:translate-x-[18px]" }) })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "Column Presets" }), _jsx("div", { className: "grid grid-cols-2 gap-1.5", children: COLUMN_PRESETS.map((preset) => (_jsxs("button", { type: "button", onClick: () => updateSetting('__columnPreset', preset.widths), className: "px-2 py-2 rounded-md border border-input bg-background hover:bg-accent transition-colors", children: [_jsx("div", { className: "flex gap-0.5 h-4", children: preset.widths.map((w, i) => (_jsx("div", { className: "bg-muted-foreground/30 rounded-sm", style: { flex: w } }, i))) }), _jsx("p", { className: "text-xs text-muted-foreground mt-1 text-center", children: preset.widths.join(' | ') })] }, preset.label))) })] }));
|
|
70
|
+
}
|
|
71
|
+
function ColumnFields({ node, updateSetting, }) {
|
|
72
|
+
const s = node.settings;
|
|
73
|
+
return (_jsxs(_Fragment, { children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "Size" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Width (1-12)" }), _jsx("input", { type: "number", min: 1, max: 12, value: s.width, onChange: (e) => updateSetting('width', Number(e.target.value)), className: INPUT_CLASS })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "Layout" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Vertical Align" }), _jsx("div", { className: "flex gap-1", children: ['top', 'center', 'bottom'].map((align) => {
|
|
74
|
+
const Icon = align === 'top' ? ArrowUpFromLine : align === 'bottom' ? ArrowDownToLine : Minus;
|
|
75
|
+
return (_jsx("button", { type: "button", onClick: () => updateSetting('verticalAlign', align), "aria-label": `Align ${align}`, className: `flex-1 flex items-center justify-center py-2 rounded-md border transition-colors ${s.verticalAlign === align
|
|
76
|
+
? 'bg-primary text-primary-foreground border-primary'
|
|
77
|
+
: 'bg-background border-input hover:bg-accent'}`, children: _jsx(Icon, { size: 14 }) }, align));
|
|
78
|
+
}) })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Padding" }), _jsx("input", { type: "text", value: s.padding ?? '', onChange: (e) => updateSetting('padding', e.target.value), placeholder: "0px", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Background Color" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "color", value: s.background ?? '#ffffff', onChange: (e) => updateSetting('background', e.target.value), className: "h-9 w-9 rounded-md border border-input cursor-pointer" }), _jsx("input", { type: "text", value: s.background ?? '', onChange: (e) => updateSetting('background', e.target.value), placeholder: "transparent", className: `${INPUT_CLASS} flex-1` })] })] })] }));
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=NodeSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeSettings.js","sourceRoot":"","sources":["../../../src/views/page-builder/NodeSettings.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface PageBuilderProps {
|
|
2
|
+
documentId?: string;
|
|
3
|
+
collectionSlug: string;
|
|
4
|
+
config: any;
|
|
5
|
+
onNavigate: (path: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function PageBuilder({ documentId, collectionSlug, config, onNavigate, }: PageBuilderProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=PageBuilder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageBuilder.d.ts","sourceRoot":"","sources":["../../../src/views/page-builder/PageBuilder.tsx"],"names":[],"mappings":"AAoBA,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAUD,wBAAgB,WAAW,CAAC,EAC1B,UAAU,EACV,cAAc,EACd,MAAM,EACN,UAAU,GACX,EAAE,gBAAgB,2CAuPlB"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
4
|
+
import { Loader2, AlertTriangle } from 'lucide-react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { cmsApi } from '../../lib/api.js';
|
|
7
|
+
import { ErrorBoundary } from '../../components/ErrorBoundary.js';
|
|
8
|
+
import { useBuilderState, } from '../../hooks/useBuilderState.js';
|
|
9
|
+
import { BuilderToolbar } from './BuilderToolbar.js';
|
|
10
|
+
import { BottomBar } from './BottomBar.js';
|
|
11
|
+
import { BuilderCanvas } from './canvas/index.js';
|
|
12
|
+
import { ContextPanel } from './ContextPanel.js';
|
|
13
|
+
import { AIGenerateDialog } from './AIGenerateDialog.js';
|
|
14
|
+
const DEVICE_WIDTHS = {
|
|
15
|
+
desktop: '100%',
|
|
16
|
+
tablet: '768px',
|
|
17
|
+
mobile: '375px',
|
|
18
|
+
};
|
|
19
|
+
export function PageBuilder({ documentId, collectionSlug, config, onNavigate, }) {
|
|
20
|
+
const [loading, setLoading] = useState(!!documentId);
|
|
21
|
+
const [loadError, setLoadError] = useState(null);
|
|
22
|
+
const [saving, setSaving] = useState(false);
|
|
23
|
+
const [status, setStatus] = useState('DRAFT');
|
|
24
|
+
const [aiDialogOpen, setAiDialogOpen] = useState(false);
|
|
25
|
+
const builder = useBuilderState();
|
|
26
|
+
const { tree, pageSettings, deviceMode, dirty, canUndo, canRedo, selectedNodeId, selectedNode, activeTab, showGridOverlay, selectNode, setDeviceMode, setActiveTab, setPageSettings, setShowGridOverlay, addSection, addRowToSection, addBlockToColumn, addNodeAtId, removeNodeById, moveNodeById, updateSettings, updateBlock, duplicateNode, moveNodeUp, moveNodeDown, undo, redo, markClean, replaceTree, } = builder;
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (!documentId) {
|
|
29
|
+
setLoading(false);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let cancelled = false;
|
|
33
|
+
async function loadDocument() {
|
|
34
|
+
const res = await cmsApi(`/collections/${collectionSlug}/${documentId}`);
|
|
35
|
+
if (cancelled)
|
|
36
|
+
return;
|
|
37
|
+
if (res.error) {
|
|
38
|
+
setLoadError(res.error);
|
|
39
|
+
setLoading(false);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const doc = res.data;
|
|
43
|
+
if (doc?.layout) {
|
|
44
|
+
replaceTree(doc.layout);
|
|
45
|
+
markClean();
|
|
46
|
+
}
|
|
47
|
+
if (doc?.pageSettings) {
|
|
48
|
+
setPageSettings(doc.pageSettings);
|
|
49
|
+
}
|
|
50
|
+
if (doc?.status) {
|
|
51
|
+
setStatus(doc.status);
|
|
52
|
+
}
|
|
53
|
+
if (doc?.title) {
|
|
54
|
+
setPageSettings({ title: doc.title });
|
|
55
|
+
}
|
|
56
|
+
setLoading(false);
|
|
57
|
+
}
|
|
58
|
+
loadDocument();
|
|
59
|
+
return () => { cancelled = true; };
|
|
60
|
+
}, [documentId, collectionSlug]);
|
|
61
|
+
const handleSave = useCallback(async () => {
|
|
62
|
+
setSaving(true);
|
|
63
|
+
const body = JSON.stringify({
|
|
64
|
+
layout: tree,
|
|
65
|
+
pageSettings,
|
|
66
|
+
title: pageSettings.title,
|
|
67
|
+
slug: pageSettings.slug,
|
|
68
|
+
});
|
|
69
|
+
const endpoint = documentId
|
|
70
|
+
? `/collections/${collectionSlug}/${documentId}`
|
|
71
|
+
: `/collections/${collectionSlug}`;
|
|
72
|
+
const method = documentId ? 'PUT' : 'POST';
|
|
73
|
+
const res = await cmsApi(endpoint, { method, body });
|
|
74
|
+
setSaving(false);
|
|
75
|
+
if (res.error) {
|
|
76
|
+
toast.error(res.error);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
markClean();
|
|
80
|
+
toast.success('Page saved');
|
|
81
|
+
if (!documentId && res.data?.id) {
|
|
82
|
+
onNavigate(`/pages/${res.data.id}/builder`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate]);
|
|
86
|
+
const handlePublish = useCallback(async () => {
|
|
87
|
+
setSaving(true);
|
|
88
|
+
const body = JSON.stringify({
|
|
89
|
+
layout: tree,
|
|
90
|
+
pageSettings,
|
|
91
|
+
title: pageSettings.title,
|
|
92
|
+
slug: pageSettings.slug,
|
|
93
|
+
status: 'PUBLISHED',
|
|
94
|
+
});
|
|
95
|
+
const endpoint = documentId
|
|
96
|
+
? `/collections/${collectionSlug}/${documentId}`
|
|
97
|
+
: `/collections/${collectionSlug}`;
|
|
98
|
+
const method = documentId ? 'PUT' : 'POST';
|
|
99
|
+
const res = await cmsApi(endpoint, { method, body });
|
|
100
|
+
setSaving(false);
|
|
101
|
+
if (res.error) {
|
|
102
|
+
toast.error(res.error);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
markClean();
|
|
106
|
+
setStatus('PUBLISHED');
|
|
107
|
+
toast.success('Page published');
|
|
108
|
+
if (!documentId && res.data?.id) {
|
|
109
|
+
onNavigate(`/pages/${res.data.id}/builder`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}, [tree, pageSettings, documentId, collectionSlug, markClean, onNavigate]);
|
|
113
|
+
const handleAIAccept = useCallback((generatedTree) => {
|
|
114
|
+
replaceTree(generatedTree);
|
|
115
|
+
}, [replaceTree]);
|
|
116
|
+
if (loading) {
|
|
117
|
+
return (_jsx("div", { className: "h-full flex items-center justify-center bg-background", children: _jsx(Loader2, { className: "animate-spin text-muted-foreground", size: 24 }) }));
|
|
118
|
+
}
|
|
119
|
+
if (loadError) {
|
|
120
|
+
return (_jsx("div", { className: "h-full flex items-center justify-center bg-background", children: _jsxs("div", { className: "flex items-center gap-3 rounded-lg border border-destructive/30 bg-destructive/5 p-4 max-w-md", children: [_jsx(AlertTriangle, { className: "text-destructive shrink-0", size: 20 }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Failed to load page" }), _jsx("p", { className: "text-sm text-muted-foreground mt-1", children: loadError })] })] }) }));
|
|
121
|
+
}
|
|
122
|
+
const canvasWidth = DEVICE_WIDTHS[deviceMode];
|
|
123
|
+
const isConstrained = deviceMode !== 'desktop';
|
|
124
|
+
return (_jsxs(ErrorBoundary, { children: [_jsxs("div", { className: "h-full flex flex-col bg-background overflow-hidden", children: [_jsx(BuilderToolbar, { collectionSlug: collectionSlug, pageSettings: pageSettings, status: status, dirty: dirty, saving: saving, canUndo: canUndo, canRedo: canRedo, deviceMode: deviceMode, onNavigate: onNavigate, onTitleChange: (title) => setPageSettings({ title }), onUndo: undo, onRedo: redo, onDeviceMode: setDeviceMode, onSave: handleSave, onPublish: handlePublish, onOpenAI: () => setAiDialogOpen(true) }), _jsxs("div", { className: "flex-1 flex overflow-hidden", children: [_jsx("div", { className: "flex-1 overflow-auto bg-muted", children: _jsx("div", { className: "mx-auto h-full max-w-full transition-all duration-200", style: { width: canvasWidth }, children: _jsx("div", { className: `h-full bg-background ${isConstrained ? 'shadow-lg border-x border-border' : ''}`, children: _jsx(BuilderCanvas, { tree: tree, selectedNodeId: selectedNodeId, showGridOverlay: showGridOverlay, deviceMode: deviceMode, onSelectNode: selectNode }) }) }) }), _jsx("div", { className: "w-[35%] min-w-[280px] max-w-[420px] border-l border-border bg-card overflow-y-auto", children: _jsx(ContextPanel, { activeTab: activeTab, onTabChange: setActiveTab, selectedNode: selectedNode, tree: tree, pageSettings: pageSettings, onUpdateSettings: updateSettings, onUpdateBlock: updateBlock, onRemoveNode: removeNodeById, onDuplicateNode: duplicateNode, onMoveNodeUp: moveNodeUp, onMoveNodeDown: moveNodeDown, onPageSettingsChange: setPageSettings, onAddRow: addRowToSection, config: config }) })] }), _jsx(BottomBar, { deviceMode: deviceMode, showGridOverlay: showGridOverlay, onAddSection: addSection, onToggleGrid: setShowGridOverlay })] }), _jsx(AIGenerateDialog, { open: aiDialogOpen, onClose: () => setAiDialogOpen(false), onAccept: handleAIAccept })] }));
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=PageBuilder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageBuilder.js","sourceRoot":"","sources":["../../../src/views/page-builder/PageBuilder.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PageSettings } from '../../hooks/useBuilderState.js';
|
|
2
|
+
export interface PageSettingsProps {
|
|
3
|
+
settings: PageSettings;
|
|
4
|
+
onChange: (settings: Partial<PageSettings>) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function PageSettingsEditor({ settings, onChange }: PageSettingsProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=PageSettings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageSettings.d.ts","sourceRoot":"","sources":["../../../src/views/page-builder/PageSettings.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;CACrD;AAoBD,wBAAgB,kBAAkB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CAoI3E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback } from 'react';
|
|
4
|
+
const INPUT_CLASS = 'w-full px-3 py-2 text-sm bg-background border border-input rounded-md focus:outline-none focus:ring-2 focus:ring-ring';
|
|
5
|
+
const LABEL_CLASS = 'text-sm font-medium text-foreground mb-1 block';
|
|
6
|
+
const SECTION_HEADING_CLASS = 'text-xs font-medium uppercase tracking-wider text-muted-foreground mb-2';
|
|
7
|
+
const SCHEMA_TYPES = [
|
|
8
|
+
'Article',
|
|
9
|
+
'LocalBusiness',
|
|
10
|
+
'WebPage',
|
|
11
|
+
'Product',
|
|
12
|
+
'FAQPage',
|
|
13
|
+
'Organization',
|
|
14
|
+
'Event',
|
|
15
|
+
'Recipe',
|
|
16
|
+
'HowTo',
|
|
17
|
+
'BreadcrumbList',
|
|
18
|
+
];
|
|
19
|
+
export function PageSettingsEditor({ settings, onChange }) {
|
|
20
|
+
const update = useCallback((key, value) => {
|
|
21
|
+
onChange({ [key]: value });
|
|
22
|
+
}, [onChange]);
|
|
23
|
+
const metaTitleLength = (settings.metaTitle ?? '').length;
|
|
24
|
+
const metaDescLength = (settings.metaDescription ?? '').length;
|
|
25
|
+
return (_jsxs("div", { className: "space-y-4 p-4", children: [_jsx("p", { className: SECTION_HEADING_CLASS, children: "General" }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Title" }), _jsx("input", { type: "text", value: settings.title, onChange: (e) => update('title', e.target.value), placeholder: "Page title", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Slug" }), _jsx("input", { type: "text", value: settings.slug, onChange: (e) => update('slug', e.target.value), placeholder: "/page-slug", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Template" }), _jsx("input", { type: "text", value: settings.template ?? '', onChange: (e) => update('template', e.target.value), placeholder: "default", className: INPUT_CLASS, readOnly: true })] }), _jsx("p", { className: SECTION_HEADING_CLASS, children: "SEO" }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("label", { className: "text-sm font-medium text-foreground", children: "Meta Title" }), _jsxs("span", { className: `text-xs ${metaTitleLength > 60 ? 'text-destructive' : 'text-muted-foreground'}`, children: [metaTitleLength, "/60"] })] }), _jsx("input", { type: "text", value: settings.metaTitle ?? '', onChange: (e) => update('metaTitle', e.target.value), placeholder: "SEO title", maxLength: 100, className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("label", { className: "text-sm font-medium text-foreground", children: "Meta Description" }), _jsxs("span", { className: `text-xs ${metaDescLength > 160 ? 'text-destructive' : 'text-muted-foreground'}`, children: [metaDescLength, "/160"] })] }), _jsx("textarea", { value: settings.metaDescription ?? '', onChange: (e) => update('metaDescription', e.target.value), placeholder: "Brief description for search engines", rows: 3, maxLength: 250, className: `${INPUT_CLASS} resize-y` })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "OG Image" }), _jsx("input", { type: "text", value: settings.ogImage ?? '', onChange: (e) => update('ogImage', e.target.value), placeholder: "https://example.com/image.jpg", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Focus Keyphrase" }), _jsx("input", { type: "text", value: settings.focusKeyphrase ?? '', onChange: (e) => update('focusKeyphrase', e.target.value), placeholder: "primary keyword", className: INPUT_CLASS })] }), _jsxs("div", { children: [_jsx("label", { className: LABEL_CLASS, children: "Schema Type" }), _jsxs("select", { value: settings.schemaType ?? '', onChange: (e) => update('schemaType', e.target.value), className: INPUT_CLASS, children: [_jsx("option", { value: "", children: "Select schema type..." }), SCHEMA_TYPES.map((type) => (_jsx("option", { value: type, children: type }, type)))] })] })] }));
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=PageSettings.js.map
|