@jhits/plugin-newsletter 0.0.15 → 0.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/email-utils.d.ts.map +1 -1
- package/dist/api/email-utils.js +45 -4
- package/dist/api/handlers/newsletters.d.ts.map +1 -1
- package/dist/api/handlers/newsletters.js +33 -16
- package/dist/api/handlers/send-newsletter.d.ts.map +1 -1
- package/dist/api/handlers/send-newsletter.js +54 -6
- package/dist/api/handlers/settings.d.ts.map +1 -1
- package/dist/api/handlers/settings.js +51 -1
- package/dist/index.d.ts +27 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -122
- package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -1
- package/dist/lib/blocks/BlockRenderer.js +14 -2
- package/dist/lib/email/EmailRenderer.d.ts +1 -0
- package/dist/lib/email/EmailRenderer.d.ts.map +1 -1
- package/dist/lib/email/EmailRenderer.js +31 -19
- package/dist/lib/utils/config-resolver.d.ts +33 -0
- package/dist/lib/utils/config-resolver.d.ts.map +1 -0
- package/dist/lib/utils/config-resolver.js +47 -0
- package/dist/registry/BlockRegistry.d.ts +9 -1
- package/dist/registry/BlockRegistry.d.ts.map +1 -1
- package/dist/registry/BlockRegistry.js +126 -8
- package/dist/state/EditorContext.d.ts +11 -1
- package/dist/state/EditorContext.d.ts.map +1 -1
- package/dist/state/EditorContext.js +23 -5
- package/dist/state/types.d.ts +12 -0
- package/dist/state/types.d.ts.map +1 -1
- package/dist/types/block.d.ts +9 -0
- package/dist/types/block.d.ts.map +1 -1
- package/dist/types/newsletter.d.ts +4 -0
- package/dist/types/newsletter.d.ts.map +1 -1
- package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -1
- package/dist/views/CanvasEditor/BlockWrapper.js +24 -3
- package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
- package/dist/views/CanvasEditor/CanvasEditorView.js +77 -17
- package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -1
- package/dist/views/CanvasEditor/EditorBody.js +1 -1
- package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/EditorCanvas.js +158 -100
- package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +3 -1
- package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
- package/dist/views/CanvasEditor/components/EditorSidebar.js +3 -3
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +1 -1
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -1
- package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.js +6 -40
- package/dist/views/NewsletterManager.d.ts.map +1 -1
- package/dist/views/NewsletterManager.js +87 -5
- package/dist/views/components/DomainPromptModal.d.ts +13 -0
- package/dist/views/components/DomainPromptModal.d.ts.map +1 -0
- package/dist/views/components/DomainPromptModal.js +58 -0
- package/dist/views/components/NewsletterCard.d.ts +16 -0
- package/dist/views/components/NewsletterCard.d.ts.map +1 -0
- package/dist/views/components/NewsletterCard.js +94 -0
- package/dist/views/components/NewsletterGrid.d.ts +16 -0
- package/dist/views/components/NewsletterGrid.d.ts.map +1 -0
- package/dist/views/components/NewsletterGrid.js +13 -0
- package/dist/views/components/SendNewsletterModal.d.ts.map +1 -1
- package/dist/views/components/SendNewsletterModal.js +91 -22
- package/dist/views/components/SmtpSettingsModal.d.ts.map +1 -1
- package/dist/views/components/SmtpSettingsModal.js +10 -0
- package/dist/views/components/TestEmailModal.d.ts.map +1 -1
- package/dist/views/components/TestEmailModal.js +86 -17
- package/package.json +53 -9
- package/src/api/email-utils.ts +53 -4
- package/src/api/handlers/newsletters.ts +40 -20
- package/src/api/handlers/send-newsletter.ts +65 -6
- package/src/api/handlers/settings.ts +60 -2
- package/src/index.tsx +49 -155
- package/src/lib/blocks/BlockRenderer.tsx +16 -2
- package/src/lib/email/EmailRenderer.tsx +31 -20
- package/src/lib/utils/config-resolver.ts +71 -0
- package/src/registry/BlockRegistry.tsx +255 -0
- package/src/state/EditorContext.tsx +43 -8
- package/src/state/types.ts +16 -0
- package/src/types/block.ts +10 -0
- package/src/types/newsletter.ts +5 -0
- package/src/views/CanvasEditor/BlockWrapper.tsx +27 -2
- package/src/views/CanvasEditor/CanvasEditorView.tsx +142 -61
- package/src/views/CanvasEditor/EditorBody.tsx +17 -13
- package/src/views/CanvasEditor/components/EditorCanvas.tsx +178 -115
- package/src/views/CanvasEditor/components/EditorSidebar.tsx +57 -2
- package/src/views/CanvasEditor/hooks/useRegisteredBlocks.ts +6 -45
- package/src/views/NewsletterManager.tsx +164 -6
- package/src/views/components/DomainPromptModal.tsx +160 -0
- package/src/views/components/NewsletterCard.tsx +212 -0
- package/src/views/components/NewsletterGrid.tsx +48 -0
- package/src/views/components/SendNewsletterModal.tsx +270 -184
- package/src/views/components/SmtpSettingsModal.tsx +11 -0
- package/src/views/components/TestEmailModal.tsx +235 -149
- package/src/registry/BlockRegistry.ts +0 -53
|
@@ -1,10 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Type, Heading as HeadingIcon, List, Minus } from 'lucide-react';
|
|
3
|
+
// --- Default Block Components ---
|
|
4
|
+
// Paragraph
|
|
5
|
+
const DefaultParagraphEdit = ({ block, onUpdate }) => (_jsx("textarea", { value: block.data.text || '', onChange: (e) => onUpdate({ text: e.target.value }), onInput: (e) => {
|
|
6
|
+
const target = e.target;
|
|
7
|
+
target.style.height = 'auto';
|
|
8
|
+
target.style.height = `${target.scrollHeight}px`;
|
|
9
|
+
}, placeholder: "Type your text...", className: "w-full bg-transparent border-none outline-none focus:ring-0 p-0 resize-none min-h-[1.5em] font-serif text-[18px] leading-[1.625] text-[#1a2e26] overflow-hidden" }));
|
|
10
|
+
const DefaultParagraphPreview = ({ block }) => (_jsx("p", { className: "font-serif text-[18px] leading-[1.625] text-[#1a2e26]", dangerouslySetInnerHTML: { __html: block.data.html || block.data.text || '' } }));
|
|
11
|
+
// Heading
|
|
12
|
+
const DefaultHeadingEdit = ({ block, onUpdate }) => {
|
|
13
|
+
const level = block.data.level || 2;
|
|
14
|
+
const fontSize = level === 1 ? '48px' : level === 2 ? '36px' : level === 3 ? '30px' : '20px';
|
|
15
|
+
return (_jsx("input", { type: "text", value: block.data.text || '', onChange: (e) => onUpdate({ text: e.target.value }), placeholder: "Heading...", style: { fontSize, lineHeight: '1.2' }, className: "w-full bg-transparent border-none outline-none focus:ring-0 p-0 font-serif font-bold text-[#1a2e26]" }));
|
|
16
|
+
};
|
|
17
|
+
const DefaultHeadingPreview = ({ block }) => {
|
|
18
|
+
const level = block.data.level || 2;
|
|
19
|
+
const fontSize = level === 1 ? '48px' : level === 2 ? '36px' : level === 3 ? '30px' : '20px';
|
|
20
|
+
const Tag = `h${level}`;
|
|
21
|
+
return (_jsx(Tag, { style: { fontSize, lineHeight: '1.2' }, className: "font-serif font-bold text-[#1a2e26]", dangerouslySetInnerHTML: { __html: block.data.text || '' } }));
|
|
22
|
+
};
|
|
23
|
+
// List
|
|
24
|
+
const DefaultListEdit = ({ block, onUpdate }) => {
|
|
25
|
+
const items = Array.isArray(block.data.items) ? block.data.items : [''];
|
|
26
|
+
return (_jsxs("div", { className: "space-y-2", children: [items.map((item, i) => (_jsxs("div", { className: "flex gap-2", children: [_jsx("span", { className: "text-neutral-400", children: "\u2022" }), _jsx("input", { type: "text", value: typeof item === 'string' ? item : item.text || '', onChange: (e) => {
|
|
27
|
+
const newItems = [...items];
|
|
28
|
+
newItems[i] = e.target.value;
|
|
29
|
+
onUpdate({ items: newItems });
|
|
30
|
+
}, className: "flex-1 bg-transparent border-none outline-none focus:ring-0 p-0 text-[18px] leading-[1.625] font-serif" })] }, i))), _jsx("button", { type: "button", onClick: () => onUpdate({ items: [...items, ''] }), className: "text-xs text-primary font-bold hover:underline", children: "+ Add Item" })] }));
|
|
31
|
+
};
|
|
32
|
+
const DefaultListPreview = ({ block }) => {
|
|
33
|
+
const items = Array.isArray(block.data.items) ? block.data.items : [];
|
|
34
|
+
const Tag = block.data.type === 'ol' ? 'ol' : 'ul';
|
|
35
|
+
return (_jsx(Tag, { className: "list-disc pl-5 space-y-1 font-serif text-[18px] leading-[1.625] text-[#1a2e26]", children: items.map((item, i) => (_jsx("li", { children: typeof item === 'string' ? item : item.text || '' }, i))) }));
|
|
36
|
+
};
|
|
8
37
|
/**
|
|
9
38
|
* Block Registry Implementation
|
|
10
39
|
* Singleton that manages all block types in the system
|
|
@@ -12,12 +41,100 @@
|
|
|
12
41
|
class BlockRegistryImpl {
|
|
13
42
|
constructor() {
|
|
14
43
|
this.blocks = new Map();
|
|
44
|
+
// Register default blocks on instantiation (server & client)
|
|
45
|
+
this.registerDefaultBlocks();
|
|
46
|
+
}
|
|
47
|
+
registerDefaultBlocks() {
|
|
48
|
+
const defaults = [
|
|
49
|
+
{
|
|
50
|
+
type: 'paragraph',
|
|
51
|
+
name: 'Paragraph',
|
|
52
|
+
description: 'Simple text paragraph',
|
|
53
|
+
icon: Type,
|
|
54
|
+
category: 'text',
|
|
55
|
+
defaultData: { text: '' },
|
|
56
|
+
components: { Edit: DefaultParagraphEdit, Preview: DefaultParagraphPreview, Icon: Type }
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
type: 'heading',
|
|
60
|
+
name: 'Heading',
|
|
61
|
+
description: 'Section heading',
|
|
62
|
+
icon: HeadingIcon,
|
|
63
|
+
category: 'text',
|
|
64
|
+
defaultData: { text: '', level: 2 },
|
|
65
|
+
components: { Edit: DefaultHeadingEdit, Preview: DefaultHeadingPreview, Icon: HeadingIcon }
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'list',
|
|
69
|
+
name: 'List',
|
|
70
|
+
description: 'Bullet or numbered list',
|
|
71
|
+
icon: List,
|
|
72
|
+
category: 'text',
|
|
73
|
+
defaultData: { items: [''], type: 'ul' },
|
|
74
|
+
components: { Edit: DefaultListEdit, Preview: DefaultListPreview, Icon: List }
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
type: 'divider',
|
|
78
|
+
name: 'Divider',
|
|
79
|
+
description: 'Horizontal separator',
|
|
80
|
+
icon: Minus,
|
|
81
|
+
category: 'layout',
|
|
82
|
+
defaultData: {},
|
|
83
|
+
components: {
|
|
84
|
+
Edit: () => _jsx("hr", { className: "my-4 border-t border-neutral-200" }),
|
|
85
|
+
Preview: () => _jsx("hr", { className: "my-4 border-t border-neutral-200" }),
|
|
86
|
+
Icon: Minus
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
];
|
|
90
|
+
for (const def of defaults) {
|
|
91
|
+
// Use register to ensure it's also added to window
|
|
92
|
+
this.register(def);
|
|
93
|
+
}
|
|
15
94
|
}
|
|
16
95
|
register(definition) {
|
|
17
96
|
this.blocks.set(definition.type, definition);
|
|
97
|
+
// Also attach to window for cross-context access
|
|
98
|
+
if (typeof window !== 'undefined') {
|
|
99
|
+
if (!window.__JHITS_NEWSLETTER_REGISTRY__) {
|
|
100
|
+
window.__JHITS_NEWSLETTER_REGISTRY__ = new Map();
|
|
101
|
+
}
|
|
102
|
+
window.__JHITS_NEWSLETTER_REGISTRY__.set(definition.type, definition);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Register multiple client blocks at once
|
|
107
|
+
* This is the primary method for client applications to register their blocks
|
|
108
|
+
*/
|
|
109
|
+
registerClientBlocks(definitions) {
|
|
110
|
+
for (const def of definitions) {
|
|
111
|
+
if (!def.type || !def.name || !def.components)
|
|
112
|
+
continue;
|
|
113
|
+
if (!def.components.Edit || !def.components.Preview)
|
|
114
|
+
continue;
|
|
115
|
+
const blockDefinition = {
|
|
116
|
+
type: def.type,
|
|
117
|
+
name: def.name,
|
|
118
|
+
description: def.description,
|
|
119
|
+
icon: def.icon || def.components.Icon,
|
|
120
|
+
defaultData: def.defaultData,
|
|
121
|
+
validate: def.validate,
|
|
122
|
+
isContainer: def.isContainer,
|
|
123
|
+
allowedChildren: def.allowedChildren,
|
|
124
|
+
category: def.category || 'custom',
|
|
125
|
+
components: def.components,
|
|
126
|
+
};
|
|
127
|
+
this.register(blockDefinition);
|
|
128
|
+
}
|
|
18
129
|
}
|
|
19
130
|
get(type) {
|
|
20
|
-
|
|
131
|
+
const block = this.blocks.get(type);
|
|
132
|
+
if (block)
|
|
133
|
+
return block;
|
|
134
|
+
if (typeof window !== 'undefined' && window.__JHITS_NEWSLETTER_REGISTRY__) {
|
|
135
|
+
return window.__JHITS_NEWSLETTER_REGISTRY__.get(type);
|
|
136
|
+
}
|
|
137
|
+
return undefined;
|
|
21
138
|
}
|
|
22
139
|
getAll() {
|
|
23
140
|
return Array.from(this.blocks.values());
|
|
@@ -27,6 +144,7 @@ class BlockRegistryImpl {
|
|
|
27
144
|
}
|
|
28
145
|
clear() {
|
|
29
146
|
this.blocks.clear();
|
|
147
|
+
this.registerDefaultBlocks(); // Re-add defaults after clear
|
|
30
148
|
}
|
|
31
149
|
}
|
|
32
150
|
// Export singleton instance
|
|
@@ -31,15 +31,25 @@ export interface EditorProviderProps {
|
|
|
31
31
|
/** Background color for dark mode (optional) */
|
|
32
32
|
dark?: string;
|
|
33
33
|
};
|
|
34
|
+
/** Localized strings for modular blocks in the editor */
|
|
35
|
+
translations?: Record<string, any>;
|
|
34
36
|
/** If true, this editor is for the welcome email */
|
|
35
37
|
isWelcomeEmail?: boolean;
|
|
38
|
+
/** Email configuration (logo, footer, etc.) */
|
|
39
|
+
emailConfig?: {
|
|
40
|
+
logoUrl?: string;
|
|
41
|
+
logoAlt?: string;
|
|
42
|
+
footerText?: string;
|
|
43
|
+
};
|
|
44
|
+
/** Global translations for unsubscribe text */
|
|
45
|
+
unsubscribeTranslations?: Record<string, string>;
|
|
36
46
|
}
|
|
37
47
|
/**
|
|
38
48
|
* Editor Provider
|
|
39
49
|
* Provides editor state and actions to child components
|
|
40
50
|
* Automatically registers client-provided blocks on mount
|
|
41
51
|
*/
|
|
42
|
-
export declare function EditorProvider({ children, initialState, onSave, customBlocks, darkMode, backgroundColors, isWelcomeEmail }: EditorProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
export declare function EditorProvider({ children, initialState, onSave, customBlocks, darkMode, backgroundColors, translations, isWelcomeEmail, emailConfig, unsubscribeTranslations }: EditorProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
43
53
|
/**
|
|
44
54
|
* Hook to access editor context
|
|
45
55
|
* @throws Error if used outside EditorProvider
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../src/state/EditorContext.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAmG,MAAM,OAAO,CAAC;AAExH,OAAO,EAAE,WAAW,EAAoC,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAG5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAMvD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,sCAAsC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF;;;OAGG;IACH,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,gDAAgD;QAChD,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorContext.d.ts","sourceRoot":"","sources":["../../src/state/EditorContext.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAmG,MAAM,OAAO,CAAC;AAExH,OAAO,EAAE,WAAW,EAAoC,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAG5F,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAMvD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,sCAAsC;IACtC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClF;;;OAGG;IACH,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;QACd,gDAAgD;QAChD,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACnC,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,+CAA+C;IAC/C,WAAW,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,+CAA+C;IAC/C,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAC3B,QAAQ,EACR,YAAY,EACZ,MAAM,EACN,YAAiB,EACjB,QAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,uBAAuB,EAC1B,EAAE,mBAAmB,2CAoOrB;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAM9C"}
|
|
@@ -16,19 +16,33 @@ const EditorContext = createContext(null);
|
|
|
16
16
|
* Provides editor state and actions to child components
|
|
17
17
|
* Automatically registers client-provided blocks on mount
|
|
18
18
|
*/
|
|
19
|
-
export function EditorProvider({ children, initialState, onSave, customBlocks = [], darkMode = true, backgroundColors, isWelcomeEmail }) {
|
|
20
|
-
|
|
19
|
+
export function EditorProvider({ children, initialState, onSave, customBlocks = [], darkMode = true, backgroundColors, translations, isWelcomeEmail, emailConfig, unsubscribeTranslations }) {
|
|
20
|
+
const [state, dispatch] = useReducer(editorReducer, { ...initialEditorState, ...initialState });
|
|
21
|
+
// Track registered blocks in state to trigger re-renders
|
|
22
|
+
const [registeredBlockTypes, setRegisteredBlockBlocks] = useState(() => BlockRegistry.getAll().map(b => b.type));
|
|
23
|
+
// Register client blocks on mount or when they change
|
|
21
24
|
useEffect(() => {
|
|
22
25
|
if (customBlocks && customBlocks.length > 0) {
|
|
23
26
|
try {
|
|
24
|
-
|
|
27
|
+
BlockRegistry.registerClientBlocks(customBlocks);
|
|
28
|
+
// Update state to trigger re-render
|
|
29
|
+
setRegisteredBlockBlocks(BlockRegistry.getAll().map(b => b.type));
|
|
25
30
|
}
|
|
26
31
|
catch (error) {
|
|
27
32
|
console.error('[NewsletterEditorContext] Failed to register custom blocks:', error);
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
}, [customBlocks]);
|
|
31
|
-
|
|
36
|
+
// Periodically check for new blocks in global registry (fallback for late loads)
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const interval = setInterval(() => {
|
|
39
|
+
const currentTypes = BlockRegistry.getAll().map(b => b.type);
|
|
40
|
+
if (currentTypes.length !== registeredBlockTypes.length) {
|
|
41
|
+
setRegisteredBlockBlocks(currentTypes);
|
|
42
|
+
}
|
|
43
|
+
}, 1000);
|
|
44
|
+
return () => clearInterval(interval);
|
|
45
|
+
}, [registeredBlockTypes.length]);
|
|
32
46
|
// Use a ref to always have access to the latest state in callbacks
|
|
33
47
|
const stateRef = useRef(state);
|
|
34
48
|
stateRef.current = state;
|
|
@@ -178,6 +192,10 @@ export function EditorProvider({ children, initialState, onSave, customBlocks =
|
|
|
178
192
|
dispatch,
|
|
179
193
|
darkMode,
|
|
180
194
|
backgroundColors,
|
|
195
|
+
translations,
|
|
196
|
+
emailConfig,
|
|
197
|
+
unsubscribeTranslations,
|
|
198
|
+
registeredBlockTypes,
|
|
181
199
|
helpers: {
|
|
182
200
|
addBlock,
|
|
183
201
|
updateBlock,
|
|
@@ -192,7 +210,7 @@ export function EditorProvider({ children, initialState, onSave, customBlocks =
|
|
|
192
210
|
},
|
|
193
211
|
canUndo: historyIndex > 0 && history.length > 0,
|
|
194
212
|
canRedo: historyIndex < history.length - 1,
|
|
195
|
-
}), [state, dispatch, darkMode, backgroundColors, addBlock, updateBlock, deleteBlock, duplicateBlock, moveBlock, loadNewsletter, resetEditor, save, undo, redo, historyIndex, history.length]);
|
|
213
|
+
}), [state, dispatch, darkMode, backgroundColors, translations, emailConfig, unsubscribeTranslations, registeredBlockTypes, addBlock, updateBlock, deleteBlock, duplicateBlock, moveBlock, loadNewsletter, resetEditor, save, undo, redo, historyIndex, history.length]);
|
|
196
214
|
return _jsx(EditorContext.Provider, { value: value, children: children });
|
|
197
215
|
}
|
|
198
216
|
/**
|
package/dist/state/types.d.ts
CHANGED
|
@@ -122,6 +122,18 @@ export interface EditorContextValue {
|
|
|
122
122
|
/** Background color for dark mode (optional) */
|
|
123
123
|
dark?: string;
|
|
124
124
|
};
|
|
125
|
+
/** Localized strings for modular blocks in the editor */
|
|
126
|
+
translations?: Record<string, any>;
|
|
127
|
+
/** Email configuration (logo, footer, etc.) */
|
|
128
|
+
emailConfig?: {
|
|
129
|
+
logoUrl?: string;
|
|
130
|
+
logoAlt?: string;
|
|
131
|
+
footerText?: string;
|
|
132
|
+
};
|
|
133
|
+
/** Global translations for unsubscribe text */
|
|
134
|
+
unsubscribeTranslations?: Record<string, string>;
|
|
135
|
+
/** List of registered block types (used to trigger re-renders) */
|
|
136
|
+
registeredBlockTypes: string[];
|
|
125
137
|
/** Helper functions for common operations */
|
|
126
138
|
helpers: {
|
|
127
139
|
/** Add a new block (supports nested containers via containerId) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/state/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/state/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types/block.d.ts
CHANGED
|
@@ -57,6 +57,15 @@ export interface BlockEditProps {
|
|
|
57
57
|
isDragging?: boolean;
|
|
58
58
|
/** Focus mode state */
|
|
59
59
|
focusMode?: boolean;
|
|
60
|
+
/** Additional rendering context */
|
|
61
|
+
context?: {
|
|
62
|
+
/** Site ID */
|
|
63
|
+
siteId?: string;
|
|
64
|
+
/** Locale */
|
|
65
|
+
locale?: string;
|
|
66
|
+
/** Custom render props (e.g. translations) */
|
|
67
|
+
[key: string]: unknown;
|
|
68
|
+
};
|
|
60
69
|
/** Child blocks (for container blocks like Section, Columns) */
|
|
61
70
|
childBlocks?: Block[];
|
|
62
71
|
/** Add a child block (for container blocks) */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/types/block.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../../src/types/block.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,6 +62,8 @@ export interface NewsletterMetadata {
|
|
|
62
62
|
subject: string;
|
|
63
63
|
/** Preview text */
|
|
64
64
|
previewText?: string;
|
|
65
|
+
/** Unsubscribe text (localized) */
|
|
66
|
+
unsubscribeText?: string;
|
|
65
67
|
/** Language code */
|
|
66
68
|
lang?: string;
|
|
67
69
|
/** Recipient filter (all, specific language, etc.) */
|
|
@@ -128,6 +130,8 @@ export interface NewsletterListItem {
|
|
|
128
130
|
recipientCount?: number;
|
|
129
131
|
hidden?: boolean;
|
|
130
132
|
sendHistory?: SendHistoryEntry[];
|
|
133
|
+
availableLanguages?: string[];
|
|
134
|
+
languages?: NewsletterLanguages;
|
|
131
135
|
}
|
|
132
136
|
/**
|
|
133
137
|
* Newsletter Filter Options
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"newsletter.d.ts","sourceRoot":"","sources":["../../src/types/newsletter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"newsletter.d.ts","sourceRoot":"","sources":["../../src/types/newsletter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/BlockWrapper.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;IACpB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAClD,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAc,EACd,YAAY,EACZ,UAAU,EACV,eAAe,GAClB,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"BlockWrapper.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/BlockWrapper.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAK1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAC9B,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,+DAA+D;IAC/D,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;IACpB,4BAA4B;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAClD,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,YAAY,CAAC,EACzB,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,SAAc,EACd,YAAY,EACZ,UAAU,EACV,eAAe,GAClB,EAAE,iBAAiB,2CA6HnB"}
|
|
@@ -12,7 +12,9 @@ import { useEditor } from '../../state/EditorContext';
|
|
|
12
12
|
import { SlashCommandDetector } from './components/SlashCommandDetector';
|
|
13
13
|
export function BlockWrapper({ block, onUpdate, onDelete, onMoveUp, onMoveDown, allBlocks = [], slashCommand, blockIndex, onAddBlockBelow, }) {
|
|
14
14
|
const [isHovered, setIsHovered] = useState(false);
|
|
15
|
-
const { state } = useEditor();
|
|
15
|
+
const { state, translations, registeredBlockTypes } = useEditor();
|
|
16
|
+
// We use the block definition from registry
|
|
17
|
+
// The component will re-render when registeredBlockTypes changes
|
|
16
18
|
const blockDefinition = blockRegistry.get(block.type);
|
|
17
19
|
// Check if this is a container block
|
|
18
20
|
const isContainer = isContainerBlock(block, blockRegistry);
|
|
@@ -25,6 +27,19 @@ export function BlockWrapper({ block, onUpdate, onDelete, onMoveUp, onMoveDown,
|
|
|
25
27
|
return (_jsx("div", { className: "p-4 border border-red-300 dark:border-red-700 rounded-lg bg-red-50 dark:bg-red-900/20", children: _jsxs("p", { className: "text-sm text-red-600 dark:text-red-400", children: ["Unknown block type: ", block.type] }) }));
|
|
26
28
|
}
|
|
27
29
|
const EditComponent = blockDefinition.components.Edit;
|
|
30
|
+
// Helper to check if block is empty (for easier deletion)
|
|
31
|
+
const isBlockEmpty = () => {
|
|
32
|
+
if (block.type === 'paragraph' || block.type === 'heading') {
|
|
33
|
+
const text = block.data.text || '';
|
|
34
|
+
const html = block.data.html || '';
|
|
35
|
+
return text.trim() === '' && html.trim() === '';
|
|
36
|
+
}
|
|
37
|
+
if (block.type === 'list') {
|
|
38
|
+
const items = block.data.items || [];
|
|
39
|
+
return items.length === 0 || (items.length === 1 && (typeof items[0] === 'string' ? items[0].trim() === '' : items[0].text?.trim() === ''));
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
};
|
|
28
43
|
// Store block ID when hovering for paste context
|
|
29
44
|
useEffect(() => {
|
|
30
45
|
if (isHovered) {
|
|
@@ -35,9 +50,15 @@ export function BlockWrapper({ block, onUpdate, onDelete, onMoveUp, onMoveDown,
|
|
|
35
50
|
}, [isHovered, block.id]);
|
|
36
51
|
return (_jsxs("div", { className: "group relative flex items-start gap-1 py-0.5", onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), "data-block-wrapper": true, "data-block-id": block.id, children: [_jsx("div", { className: "flex-1 min-w-0 email-block-content", children: block.type === 'paragraph' && slashCommand ? (_jsx(SlashCommandDetector, { blockId: block.id, blockIndex: blockIndex || 0, blockType: block.type, content: block.data.html || block.data.text || '', onContentChange: (content) => {
|
|
37
52
|
onUpdate({ html: content, text: content.replace(/<[^>]*>/g, '') });
|
|
38
|
-
}, slashCommand: slashCommand, onAddBlockBelow: onAddBlockBelow, children: _jsx("div", { className: "email-block-wrapper", children: _jsx(EditComponent, { block: block, onUpdate: onUpdate, onDelete: onDelete, isSelected: state.selectedBlockId === block.id, childBlocks: childBlocks
|
|
53
|
+
}, slashCommand: slashCommand, onAddBlockBelow: onAddBlockBelow, children: _jsx("div", { className: "email-block-wrapper", children: _jsx(EditComponent, { block: block, onUpdate: onUpdate, onDelete: onDelete, isSelected: state.selectedBlockId === block.id, childBlocks: childBlocks, context: {
|
|
54
|
+
locale: state.metadata.lang || 'en',
|
|
55
|
+
translations
|
|
56
|
+
} }) }) })) : (_jsx("div", { className: "email-block-wrapper", children: _jsx(EditComponent, { block: block, onUpdate: onUpdate, onDelete: onDelete, isSelected: state.selectedBlockId === block.id, childBlocks: childBlocks, context: {
|
|
57
|
+
locale: state.metadata.lang || 'en',
|
|
58
|
+
translations
|
|
59
|
+
} }) })) }), _jsx("div", { className: `flex-shrink-0 w-6 flex items-start justify-center pt-1 transition-opacity duration-150 ${isHovered ? 'opacity-100' : 'opacity-0'}`, children: _jsx("button", { onClick: (e) => {
|
|
39
60
|
e.stopPropagation();
|
|
40
|
-
if (confirm('Delete this block?')) {
|
|
61
|
+
if (isBlockEmpty() || confirm('Delete this block?')) {
|
|
41
62
|
onDelete();
|
|
42
63
|
}
|
|
43
64
|
}, className: "p-1 -mr-1 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors", title: "Delete block", children: _jsx(Trash2, { size: 16, className: "text-neutral-400 dark:text-neutral-500 hover:text-red-500 dark:hover:text-red-400 transition-colors" }) }) })] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CanvasEditorView.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/CanvasEditorView.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,qBAAqB,
|
|
1
|
+
{"version":3,"file":"CanvasEditorView.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/CanvasEditorView.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,qBAAqB,2CA6Z1J"}
|
|
@@ -11,7 +11,7 @@ import { useSlashCommand } from './hooks/useSlashCommand';
|
|
|
11
11
|
import { useNewsletterLoader, useRegisteredBlocks, useKeyboardShortcuts } from './hooks';
|
|
12
12
|
import { blockRegistry } from '../../registry';
|
|
13
13
|
export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: propsBackgroundColors, siteId, locale, isWelcomeEmail }) {
|
|
14
|
-
const { state, helpers, dispatch, darkMode: contextDarkMode, backgroundColors: contextBackgroundColors, canUndo, canRedo } = useEditor();
|
|
14
|
+
const { state, helpers, dispatch, darkMode: contextDarkMode, backgroundColors: contextBackgroundColors, emailConfig: contextEmailConfig, canUndo, canRedo } = useEditor();
|
|
15
15
|
const effectiveDarkMode = darkMode !== undefined ? darkMode : contextDarkMode;
|
|
16
16
|
const effectiveBackgroundColors = propsBackgroundColors || contextBackgroundColors;
|
|
17
17
|
const [isSidebarOpen, setSidebarOpen] = useState(true);
|
|
@@ -23,6 +23,12 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
23
23
|
const [isLoadingLanguage, setIsLoadingLanguage] = useState(true);
|
|
24
24
|
const [availableLanguages, setAvailableLanguages] = useState([locale || 'en']);
|
|
25
25
|
const [currentLanguage, setCurrentLanguage] = useState(locale || 'en');
|
|
26
|
+
// Global branding settings from SMTP
|
|
27
|
+
const [globalUnsubscribeTranslations, setGlobalUnsubscribeTranslations] = useState({
|
|
28
|
+
en: '',
|
|
29
|
+
nl: '',
|
|
30
|
+
sv: '',
|
|
31
|
+
});
|
|
26
32
|
// Get registered blocks
|
|
27
33
|
const registeredBlocks = useRegisteredBlocks();
|
|
28
34
|
// Newsletter loading - wait for language settings to be loaded first
|
|
@@ -65,6 +71,24 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
65
71
|
setPrimaryLanguage(primary);
|
|
66
72
|
setAvailableLanguages(available);
|
|
67
73
|
setCurrentLanguage(primary);
|
|
74
|
+
// Load global unsubscribe translations
|
|
75
|
+
if (smtpData.unsubscribeTranslations) {
|
|
76
|
+
setGlobalUnsubscribeTranslations(smtpData.unsubscribeTranslations);
|
|
77
|
+
}
|
|
78
|
+
// Update emailConfig with logo from SMTP settings if available
|
|
79
|
+
if (smtpData.logoUrl) {
|
|
80
|
+
if (typeof window !== 'undefined') {
|
|
81
|
+
if (!window.__JHITS_PLUGIN_PROPS__)
|
|
82
|
+
window.__JHITS_PLUGIN_PROPS__ = {};
|
|
83
|
+
if (!window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'])
|
|
84
|
+
window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'] = {};
|
|
85
|
+
const currentConfig = window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'].emailConfig || {};
|
|
86
|
+
window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'].emailConfig = {
|
|
87
|
+
...currentConfig,
|
|
88
|
+
logoUrl: smtpData.logoUrl
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
68
92
|
}
|
|
69
93
|
catch (error) {
|
|
70
94
|
console.error('Failed to fetch language settings:', error);
|
|
@@ -75,6 +99,39 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
75
99
|
};
|
|
76
100
|
fetchLanguageSettings();
|
|
77
101
|
}, []);
|
|
102
|
+
// Handle global unsubscribe text update
|
|
103
|
+
const handleGlobalUnsubscribeUpdate = async (text) => {
|
|
104
|
+
const newTranslations = {
|
|
105
|
+
...globalUnsubscribeTranslations,
|
|
106
|
+
[currentLanguage]: text
|
|
107
|
+
};
|
|
108
|
+
// Optimistic update
|
|
109
|
+
setGlobalUnsubscribeTranslations(newTranslations);
|
|
110
|
+
// Update window props for immediate preview reflection
|
|
111
|
+
if (typeof window !== 'undefined') {
|
|
112
|
+
if (!window.__JHITS_PLUGIN_PROPS__)
|
|
113
|
+
window.__JHITS_PLUGIN_PROPS__ = {};
|
|
114
|
+
if (!window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'])
|
|
115
|
+
window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'] = {};
|
|
116
|
+
window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'].unsubscribeTranslations = newTranslations;
|
|
117
|
+
}
|
|
118
|
+
try {
|
|
119
|
+
// We need current SMTP settings to save along with the new translation
|
|
120
|
+
const smtpResponse = await fetch('/api/plugin-newsletter/smtp');
|
|
121
|
+
const smtpData = await smtpResponse.json();
|
|
122
|
+
await fetch('/api/plugin-newsletter/smtp', {
|
|
123
|
+
method: 'POST',
|
|
124
|
+
headers: { 'Content-Type': 'application/json' },
|
|
125
|
+
body: JSON.stringify({
|
|
126
|
+
...smtpData,
|
|
127
|
+
unsubscribeTranslations: newTranslations
|
|
128
|
+
}),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error('Failed to save global unsubscribe translation:', error);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
78
135
|
// Handle language change for welcome email
|
|
79
136
|
const handleLanguageChange = async (newLanguage) => {
|
|
80
137
|
// Save current content first if dirty
|
|
@@ -164,17 +221,14 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
164
221
|
return;
|
|
165
222
|
}
|
|
166
223
|
// Replace the block in place by updating the blocks array directly
|
|
167
|
-
// This preserves the position and ID
|
|
168
224
|
const newBlocks = state.blocks.map((block, idx) => {
|
|
169
225
|
if (idx === blockIndex) {
|
|
170
|
-
// Replace this block with the new type
|
|
171
226
|
return {
|
|
172
227
|
...block,
|
|
173
228
|
type: blockType,
|
|
174
229
|
data: { ...blockDefinition.defaultData },
|
|
175
230
|
};
|
|
176
231
|
}
|
|
177
|
-
// Keep all other blocks unchanged
|
|
178
232
|
return block;
|
|
179
233
|
});
|
|
180
234
|
dispatch({ type: 'SET_BLOCKS', payload: newBlocks });
|
|
@@ -185,12 +239,26 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
185
239
|
}, [state.blocks, dispatch]);
|
|
186
240
|
// Slash command hook
|
|
187
241
|
const slashCommand = useSlashCommand(registeredBlocks, handleSlashCommandSelect);
|
|
242
|
+
// Lock dashboard scroll when editor is active to ensure our internal scrolling works
|
|
243
|
+
useEffect(() => {
|
|
244
|
+
if (typeof window === 'undefined')
|
|
245
|
+
return;
|
|
246
|
+
const dashboardContainer = document.querySelector('.custom-scrollbar.overflow-y-auto');
|
|
247
|
+
const originalOverflow = dashboardContainer ? dashboardContainer.style.overflow : '';
|
|
248
|
+
if (dashboardContainer) {
|
|
249
|
+
dashboardContainer.style.overflow = 'hidden';
|
|
250
|
+
}
|
|
251
|
+
return () => {
|
|
252
|
+
if (dashboardContainer) {
|
|
253
|
+
dashboardContainer.style.overflow = originalOverflow;
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
}, []);
|
|
188
257
|
// Handle save
|
|
189
258
|
const handleSave = async () => {
|
|
190
259
|
setIsSaving(true);
|
|
191
260
|
setSaveError(null);
|
|
192
261
|
try {
|
|
193
|
-
// Always pass language for saving (both welcome email and regular newsletters)
|
|
194
262
|
await helpers.save({ language: currentLanguage });
|
|
195
263
|
setIsSaving(false);
|
|
196
264
|
}
|
|
@@ -208,16 +276,8 @@ export function CanvasEditorView({ newsletterId, darkMode, backgroundColors: pro
|
|
|
208
276
|
if (isLoadingNewsletter) {
|
|
209
277
|
return (_jsx("div", { className: "h-full w-full bg-dashboard-card text-dashboard-text flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "w-8 h-8 border-4 border-primary/20 border-t-primary rounded-full animate-spin mx-auto mb-4" }), _jsx("p", { className: "text-sm text-neutral-500 dark:text-neutral-400", children: "Loading newsletter..." })] }) }));
|
|
210
278
|
}
|
|
211
|
-
return (_jsx("div", { className: "
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
else {
|
|
216
|
-
setSaveError(null);
|
|
217
|
-
}
|
|
218
|
-
}, isDirty: state.isDirty, isWelcomeEmail: isWelcomeEmail, languages: availableLanguages, currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange, onAddLanguage: handleAddLanguage }), _jsxs("div", { className: "flex flex-1 relative overflow-hidden min-h-0 flex-nowrap", children: [_jsx(EditorCanvas, { isPreviewMode: isPreviewMode, contentBlocks: state.blocks, title: state.title, siteId: siteId, locale: locale, darkMode: effectiveDarkMode, backgroundColors: effectiveBackgroundColors, metadata: state.metadata, onTitleChange: (title) => dispatch({ type: 'SET_TITLE', payload: title }), onMetadataChange: (metadata) => dispatch({ type: 'SET_METADATA', payload: metadata }), onBlockAdd: (type, index, containerId) => helpers.addBlock(type, index, containerId), onBlockUpdate: (id, data) => helpers.updateBlock(id, data), onBlockDelete: (id) => helpers.deleteBlock(id), onBlockMove: (id, newIndex, containerId) => helpers.moveBlock(id, newIndex, containerId), slashCommand: slashCommand }), !isPreviewMode && (_jsx("aside", { className: `transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] border-l border-dashboard-border bg-dashboard-sidebar overflow-y-auto overflow-x-hidden h-full ${isSidebarOpen ? 'w-80' : 'w-0 opacity-0 pointer-events-none'}`, children: _jsx(EditorSidebar, { metadata: state.metadata, status: state.status, onMetadataUpdate: (metadata) => dispatch({ type: 'SET_METADATA', payload: metadata }), defaultLanguage: primaryLanguage, isWelcomeEmail: isWelcomeEmail, languages: availableLanguages, currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange }) }))] }), slashCommand.isOpen && slashCommand.position && (_jsx(SlashCommandMenu, { blocks: slashCommand.filteredBlocks, query: slashCommand.query, selectedIndex: slashCommand.selectedIndex, onSelect: (replaceBlockId) => {
|
|
219
|
-
// Use the replaceBlockId passed from the menu (which comes from state)
|
|
220
|
-
// This ensures we use the correct block ID that was set when the menu opened
|
|
221
|
-
slashCommand.selectCurrent(replaceBlockId);
|
|
222
|
-
}, position: slashCommand.position, onClose: slashCommand.closeMenu, replaceBlockId: slashCommand.replaceBlockId }))] })) }));
|
|
279
|
+
return (_jsx("div", { className: "absolute inset-0 flex flex-col font-sans transition-colors duration-300 overflow-hidden bg-white dark:bg-neutral-950", children: isLoadingLanguage ? (_jsx("div", { className: "h-full w-full flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "w-8 h-8 border-2 border-primary border-t-transparent rounded-full animate-spin mx-auto mb-4" }), _jsx("p", { className: "text-sm text-dashboard-text-secondary", children: "Loading..." })] }) })) : (_jsxs("main", { className: "flex flex-1 flex-col relative min-h-0 overflow-hidden", children: [_jsx(ErrorBanner, { error: saveError, onDismiss: () => setSaveError(null) }), _jsx("div", { className: "flex-none z-30 border-b border-dashboard-border", children: _jsx(EditorHeader, { isPreviewMode: isPreviewMode, onPreviewToggle: () => setIsPreviewMode(!isPreviewMode), isSidebarOpen: isSidebarOpen, onSidebarToggle: () => setSidebarOpen(!isSidebarOpen), isSaving: isSaving, onSave: handleSave, onSaveError: (error) => setSaveError(error || null), isDirty: state.isDirty, isWelcomeEmail: isWelcomeEmail, languages: availableLanguages, currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange, onAddLanguage: handleAddLanguage }) }), _jsxs("div", { className: "flex-1 flex relative overflow-hidden min-h-0 flex-nowrap", children: [_jsx("div", { className: "flex-1 overflow-hidden h-full", children: _jsx(EditorCanvas, { isPreviewMode: isPreviewMode, contentBlocks: state.blocks, title: state.title, siteId: siteId, locale: currentLanguage, darkMode: effectiveDarkMode, backgroundColors: effectiveBackgroundColors, metadata: state.metadata, onTitleChange: (title) => dispatch({ type: 'SET_TITLE', payload: title }), onMetadataChange: (metadata) => dispatch({ type: 'SET_METADATA', payload: metadata }), onBlockAdd: (type, index, containerId) => helpers.addBlock(type, index, containerId), onBlockUpdate: (id, data) => helpers.updateBlock(id, data), onBlockDelete: (id) => helpers.deleteBlock(id), onBlockMove: (id, newIndex, containerId) => helpers.moveBlock(id, newIndex, containerId), slashCommand: slashCommand }) }), !isPreviewMode && (_jsx("aside", { className: `flex-none transition-all duration-500 ease-[cubic-bezier(0.4,0,0.2,1)] border-l border-dashboard-border bg-dashboard-sidebar overflow-y-auto custom-scrollbar h-full ${isSidebarOpen ? 'w-80' : 'w-0 opacity-0 pointer-events-none border-l-0'}`, children: _jsx(EditorSidebar, { metadata: state.metadata, status: state.status, onMetadataUpdate: (metadata) => dispatch({ type: 'SET_METADATA', payload: metadata }), defaultLanguage: primaryLanguage, isWelcomeEmail: isWelcomeEmail, languages: availableLanguages, currentLanguage: currentLanguage, onLanguageChange: handleLanguageChange, globalUnsubscribeText: globalUnsubscribeTranslations[currentLanguage], onGlobalUnsubscribeUpdate: handleGlobalUnsubscribeUpdate }) }))] }), slashCommand.isOpen && slashCommand.position && (_jsx("div", { className: "fixed z-50 transition-all duration-200", style: {
|
|
280
|
+
left: slashCommand.position.left,
|
|
281
|
+
top: slashCommand.position.top
|
|
282
|
+
}, children: _jsx(SlashCommandMenu, { blocks: slashCommand.filteredBlocks, query: slashCommand.query, selectedIndex: slashCommand.selectedIndex, onSelect: (replaceBlockId) => slashCommand.selectCurrent(replaceBlockId), position: slashCommand.position, onClose: slashCommand.closeMenu, replaceBlockId: slashCommand.replaceBlockId }) }))] })) }));
|
|
223
283
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorBody.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/EditorBody.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,4BAA4B;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CACrD;AAED,wBAAgB,UAAU,CAAC,EACvB,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAe,EACf,gBAAgB,EAChB,YAAY,GACf,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"EditorBody.d.ts","sourceRoot":"","sources":["../../../src/views/CanvasEditor/EditorBody.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,eAAe;IAC5B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC;IAClE,aAAa,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,WAAW,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1E,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,4BAA4B;IAC5B,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CACrD;AAED,wBAAgB,UAAU,CAAC,EACvB,MAAM,EACN,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,QAAe,EACf,gBAAgB,EAChB,YAAY,GACf,EAAE,eAAe,2CA2DjB"}
|
|
@@ -17,5 +17,5 @@ export function EditorBody({ blocks, onBlockAdd, onBlockUpdate, onBlockDelete, o
|
|
|
17
17
|
}, 0);
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
return (_jsxs("div", { className: "relative", children: [blocks.map((block, index) => (_jsxs(React.Fragment, { children: [_jsx("div", { className: "relative h-
|
|
20
|
+
return (_jsxs("div", { className: "relative", children: [blocks.map((block, index) => (_jsxs(React.Fragment, { children: [_jsx("div", { className: "relative h-4 group/add-button", children: _jsxs("div", { className: "absolute inset-x-0 top-1/2 -translate-y-1/2 flex items-center justify-center", children: [_jsx("div", { className: "w-full h-[1px] bg-neutral-100 dark:bg-neutral-800 opacity-0 group-hover/add-button:opacity-100 transition-opacity" }), _jsx("button", { onClick: () => onBlockAdd('paragraph', index), className: "mx-4 flex-shrink-0 w-6 h-6 flex items-center justify-center opacity-0 group-hover/add-button:opacity-100 transition-all hover:bg-primary hover:text-white bg-white dark:bg-neutral-800 border border-neutral-200 dark:border-neutral-700 shadow-sm rounded-full z-10", title: "Add block here", children: _jsx(Plus, { size: 14 }) }), _jsx("div", { className: "w-full h-[1px] bg-neutral-100 dark:bg-neutral-800 opacity-0 group-hover/add-button:opacity-100 transition-opacity" })] }) }), _jsx("div", { className: "relative", children: _jsx(BlockWrapper, { block: block, onUpdate: (data) => onBlockUpdate(block.id, data), onDelete: () => handleDelete(block.id, index), onMoveUp: index > 0 ? () => onBlockMove(block.id, index - 1) : undefined, onMoveDown: index < blocks.length - 1 ? () => onBlockMove(block.id, index + 1) : undefined, allBlocks: blocks, slashCommand: slashCommand, blockIndex: index, onAddBlockBelow: (blockType) => onBlockAdd(blockType, index + 1) }) })] }, block.id))), _jsx("div", { className: "relative h-12 mt-4 group/add-bottom", children: _jsx("button", { onClick: () => onBlockAdd('paragraph', blocks.length), className: "absolute left-0 top-1/2 -translate-y-1/2 w-8 h-8 flex items-center justify-center opacity-20 group-hover/add-bottom:opacity-100 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-full transition-all text-neutral-500", title: "Add block at the end", children: _jsx(Plus, { size: 18 }) }) })] }));
|
|
21
21
|
}
|