@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.
Files changed (90) hide show
  1. package/dist/api/email-utils.d.ts.map +1 -1
  2. package/dist/api/email-utils.js +45 -4
  3. package/dist/api/handlers/newsletters.d.ts.map +1 -1
  4. package/dist/api/handlers/newsletters.js +33 -16
  5. package/dist/api/handlers/send-newsletter.d.ts.map +1 -1
  6. package/dist/api/handlers/send-newsletter.js +54 -6
  7. package/dist/api/handlers/settings.d.ts.map +1 -1
  8. package/dist/api/handlers/settings.js +51 -1
  9. package/dist/index.d.ts +27 -10
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +15 -122
  12. package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -1
  13. package/dist/lib/blocks/BlockRenderer.js +14 -2
  14. package/dist/lib/email/EmailRenderer.d.ts +1 -0
  15. package/dist/lib/email/EmailRenderer.d.ts.map +1 -1
  16. package/dist/lib/email/EmailRenderer.js +31 -19
  17. package/dist/lib/utils/config-resolver.d.ts +33 -0
  18. package/dist/lib/utils/config-resolver.d.ts.map +1 -0
  19. package/dist/lib/utils/config-resolver.js +47 -0
  20. package/dist/registry/BlockRegistry.d.ts +9 -1
  21. package/dist/registry/BlockRegistry.d.ts.map +1 -1
  22. package/dist/registry/BlockRegistry.js +126 -8
  23. package/dist/state/EditorContext.d.ts +11 -1
  24. package/dist/state/EditorContext.d.ts.map +1 -1
  25. package/dist/state/EditorContext.js +23 -5
  26. package/dist/state/types.d.ts +12 -0
  27. package/dist/state/types.d.ts.map +1 -1
  28. package/dist/types/block.d.ts +9 -0
  29. package/dist/types/block.d.ts.map +1 -1
  30. package/dist/types/newsletter.d.ts +4 -0
  31. package/dist/types/newsletter.d.ts.map +1 -1
  32. package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -1
  33. package/dist/views/CanvasEditor/BlockWrapper.js +24 -3
  34. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
  35. package/dist/views/CanvasEditor/CanvasEditorView.js +77 -17
  36. package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -1
  37. package/dist/views/CanvasEditor/EditorBody.js +1 -1
  38. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -1
  39. package/dist/views/CanvasEditor/components/EditorCanvas.js +158 -100
  40. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +3 -1
  41. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
  42. package/dist/views/CanvasEditor/components/EditorSidebar.js +3 -3
  43. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +1 -1
  44. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -1
  45. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.js +6 -40
  46. package/dist/views/NewsletterManager.d.ts.map +1 -1
  47. package/dist/views/NewsletterManager.js +87 -5
  48. package/dist/views/components/DomainPromptModal.d.ts +13 -0
  49. package/dist/views/components/DomainPromptModal.d.ts.map +1 -0
  50. package/dist/views/components/DomainPromptModal.js +58 -0
  51. package/dist/views/components/NewsletterCard.d.ts +16 -0
  52. package/dist/views/components/NewsletterCard.d.ts.map +1 -0
  53. package/dist/views/components/NewsletterCard.js +94 -0
  54. package/dist/views/components/NewsletterGrid.d.ts +16 -0
  55. package/dist/views/components/NewsletterGrid.d.ts.map +1 -0
  56. package/dist/views/components/NewsletterGrid.js +13 -0
  57. package/dist/views/components/SendNewsletterModal.d.ts.map +1 -1
  58. package/dist/views/components/SendNewsletterModal.js +91 -22
  59. package/dist/views/components/SmtpSettingsModal.d.ts.map +1 -1
  60. package/dist/views/components/SmtpSettingsModal.js +10 -0
  61. package/dist/views/components/TestEmailModal.d.ts.map +1 -1
  62. package/dist/views/components/TestEmailModal.js +86 -17
  63. package/package.json +53 -9
  64. package/src/api/email-utils.ts +53 -4
  65. package/src/api/handlers/newsletters.ts +40 -20
  66. package/src/api/handlers/send-newsletter.ts +65 -6
  67. package/src/api/handlers/settings.ts +60 -2
  68. package/src/index.tsx +49 -155
  69. package/src/lib/blocks/BlockRenderer.tsx +16 -2
  70. package/src/lib/email/EmailRenderer.tsx +31 -20
  71. package/src/lib/utils/config-resolver.ts +71 -0
  72. package/src/registry/BlockRegistry.tsx +255 -0
  73. package/src/state/EditorContext.tsx +43 -8
  74. package/src/state/types.ts +16 -0
  75. package/src/types/block.ts +10 -0
  76. package/src/types/newsletter.ts +5 -0
  77. package/src/views/CanvasEditor/BlockWrapper.tsx +27 -2
  78. package/src/views/CanvasEditor/CanvasEditorView.tsx +142 -61
  79. package/src/views/CanvasEditor/EditorBody.tsx +17 -13
  80. package/src/views/CanvasEditor/components/EditorCanvas.tsx +178 -115
  81. package/src/views/CanvasEditor/components/EditorSidebar.tsx +57 -2
  82. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.ts +6 -45
  83. package/src/views/NewsletterManager.tsx +164 -6
  84. package/src/views/components/DomainPromptModal.tsx +160 -0
  85. package/src/views/components/NewsletterCard.tsx +212 -0
  86. package/src/views/components/NewsletterGrid.tsx +48 -0
  87. package/src/views/components/SendNewsletterModal.tsx +270 -184
  88. package/src/views/components/SmtpSettingsModal.tsx +11 -0
  89. package/src/views/components/TestEmailModal.tsx +235 -149
  90. package/src/registry/BlockRegistry.ts +0 -53
@@ -1 +1 @@
1
- {"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorCanvas.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAiMhE,MAAM,WAAW,iBAAiB;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,KAAK,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IACnE,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,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CACrD;AAED,wBAAgB,YAAY,CAAC,EACzB,aAAa,EACb,aAAa,EACb,KAAK,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,YAAY,GACf,EAAE,iBAAiB,2CAuPnB"}
1
+ {"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorCanvas.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAsNhE,MAAM,WAAW,iBAAiB;IAC9B,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,KAAK,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE;QACf,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IACnE,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,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;CACrD;AAED,wBAAgB,YAAY,CAAC,EACzB,aAAa,EACb,aAAa,EACb,KAAK,EACL,MAAM,EACN,MAAM,EACN,QAAQ,EACR,gBAAgB,EAChB,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,aAAa,EACb,WAAW,EACX,YAAY,GACf,EAAE,iBAAiB,2CAoQnB"}
@@ -1,17 +1,27 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useRef, useEffect, useState } from 'react';
3
+ import { useRef, useEffect, useState, useMemo } from 'react';
4
4
  import { EditorBody } from '../EditorBody';
5
+ import { useEditor } from '../../../state/EditorContext';
5
6
  import { generateNewsletterEmailHtml } from '../../../lib/email/EmailRenderer';
6
- // Add email-like styling for editor blocks
7
+ // Add email-like styling for editor blocks - Aligned with BotanicsAndYou brand styles
7
8
  const emailEditorStyles = `
9
+ .email-editor-content {
10
+ /* Newsletter Brand Variable Overrides */
11
+ --content-text-color: #1a2e26;
12
+ --content-font-family: 'Georgia', serif;
13
+ --content-font-size: 18px;
14
+ --content-line-height: 1.625;
15
+ --content-heading-font: 'Georgia', serif;
16
+ }
17
+
8
18
  .email-editor-content p,
9
19
  .email-editor-content .text-md {
10
- font-size: 15px !important;
11
- line-height: 1.8 !important;
12
- color: #1a2e26 !important;
13
- margin: 0 0 15px 0 !important;
14
- font-family: 'Georgia', serif !important;
20
+ font-size: var(--content-font-size);
21
+ line-height: var(--content-line-height);
22
+ color: var(--content-text-color);
23
+ margin: 0 0 1.5rem 0;
24
+ font-family: var(--content-font-family);
15
25
  }
16
26
 
17
27
  .email-editor-content h1,
@@ -20,52 +30,59 @@ const emailEditorStyles = `
20
30
  .email-editor-content h4,
21
31
  .email-editor-content h5,
22
32
  .email-editor-content h6 {
23
- font-family: 'Georgia', serif !important;
24
- font-weight: bold !important;
25
- color: #1a2e26 !important;
26
- margin: 20px 0 10px 0 !important;
27
- line-height: 1.3 !important;
33
+ font-family: 'Georgia', serif;
34
+ font-weight: bold;
35
+ color: #1a2e26;
36
+ margin: 2.5rem 0 1rem 0;
37
+ line-height: 1.2;
28
38
  }
29
39
 
30
40
  .email-editor-content h1 {
31
- font-size: 32px !important;
41
+ font-size: 48px;
42
+ letter-spacing: -0.02em;
32
43
  }
33
44
 
34
45
  .email-editor-content h2 {
35
- font-size: 24px !important;
46
+ font-size: 36px;
47
+ letter-spacing: -0.01em;
36
48
  }
37
49
 
38
50
  .email-editor-content h3 {
39
- font-size: 20px !important;
51
+ font-size: 30px;
52
+ }
53
+
54
+ .email-editor-content h4 {
55
+ font-size: 20px;
56
+ font-weight: 500;
40
57
  }
41
58
 
42
- .email-editor-content h4,
43
59
  .email-editor-content h5,
44
60
  .email-editor-content h6 {
45
- font-size: 18px !important;
61
+ font-size: 18px;
62
+ font-weight: 500;
46
63
  }
47
64
 
48
65
  .email-editor-content ul,
49
66
  .email-editor-content ol {
50
- margin: 15px 0 !important;
51
- padding-left: 25px !important;
52
- color: #1a2e26 !important;
53
- font-size: 15px !important;
54
- line-height: 1.8 !important;
67
+ margin: 1.5rem 0;
68
+ padding-left: 1.5rem;
69
+ color: #1a2e26;
70
+ font-size: 18px;
71
+ line-height: 1.625;
72
+ font-family: 'Georgia', serif;
55
73
  }
56
74
 
57
75
  .email-editor-content li {
58
- margin: 8px 0 !important;
59
- padding-left: 5px !important;
60
- line-height: 1.8 !important;
61
- color: #1a2e26 !important;
76
+ margin: 0.75rem 0;
77
+ padding-left: 0.25rem;
62
78
  }
63
79
 
64
80
  .email-editor-content img {
65
- max-width: 100% !important;
66
- height: auto !important;
67
- display: block !important;
68
- margin: 20px 0 !important;
81
+ max-width: 100%;
82
+ height: auto;
83
+ display: block;
84
+ margin: 2rem 0;
85
+ border-radius: 12px;
69
86
  }
70
87
 
71
88
  .email-block-wrapper {
@@ -73,15 +90,20 @@ const emailEditorStyles = `
73
90
  color: #1a2e26;
74
91
  }
75
92
 
76
- /* Ensure all blocks are visible */
93
+ /* Ensure all blocks are visible and match brand font */
94
+ .email-block-content {
95
+ font-family: 'Georgia', serif;
96
+ }
97
+
77
98
  .email-block-content > * {
78
- display: block !important;
79
- visibility: visible !important;
80
- opacity: 1 !important;
99
+ display: block;
100
+ visibility: visible;
101
+ opacity: 1;
81
102
  }
82
103
 
83
- /* Heading input styling to match preview */
84
- .email-block-content input[type="text"] {
104
+ /* Heading/Text input styling to match brand preview */
105
+ .email-block-content input[type="text"],
106
+ .email-block-content textarea {
85
107
  font-family: 'Georgia', serif !important;
86
108
  color: #1a2e26 !important;
87
109
  background: transparent !important;
@@ -194,11 +216,41 @@ const emailEditorStyles = `
194
216
  }
195
217
  `;
196
218
  export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, locale, darkMode, backgroundColors, metadata, onTitleChange, onMetadataChange, onBlockAdd, onBlockUpdate, onBlockDelete, onBlockMove, slashCommand, }) {
219
+ const { emailConfig: contextEmailConfig, unsubscribeTranslations: contextUnsubscribeTranslations } = useEditor();
220
+ // SMTP settings take priority over client config
221
+ const emailConfig = useMemo(() => {
222
+ let smtpLogoUrl = '';
223
+ let smtpUnsubscribeTranslations = {};
224
+ if (typeof window !== 'undefined') {
225
+ const pluginProps = window.__JHITS_PLUGIN_PROPS__?.['plugin-newsletter'];
226
+ if (pluginProps?.emailConfig?.logoUrl) {
227
+ smtpLogoUrl = pluginProps.emailConfig.logoUrl;
228
+ }
229
+ if (pluginProps?.unsubscribeTranslations) {
230
+ smtpUnsubscribeTranslations = pluginProps.unsubscribeTranslations;
231
+ }
232
+ }
233
+ return {
234
+ ...contextEmailConfig,
235
+ logoUrl: smtpLogoUrl || contextEmailConfig?.logoUrl,
236
+ unsubscribeTranslations: {
237
+ en: 'Unsubscribe',
238
+ nl: 'Afmelden',
239
+ sv: 'Avanmälan',
240
+ ...contextUnsubscribeTranslations,
241
+ ...smtpUnsubscribeTranslations
242
+ }
243
+ };
244
+ }, [contextEmailConfig, contextUnsubscribeTranslations]);
197
245
  const titleRef = useRef(null);
198
246
  // Inject email-like styles for editor
199
247
  useEffect(() => {
200
248
  const styleId = 'email-editor-styles';
201
- if (!document.getElementById(styleId)) {
249
+ const existingStyle = document.getElementById(styleId);
250
+ if (existingStyle) {
251
+ existingStyle.textContent = emailEditorStyles;
252
+ }
253
+ else {
202
254
  const style = document.createElement('style');
203
255
  style.id = styleId;
204
256
  style.textContent = emailEditorStyles;
@@ -212,12 +264,12 @@ export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, loca
212
264
  titleRef.current.style.height = `${titleRef.current.scrollHeight}px`;
213
265
  }
214
266
  }, [title]);
215
- return (_jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden pb-40 custom-scrollbar selection:bg-primary/20 dark:selection:bg-primary/30 min-h-0", style: {
267
+ return (_jsx("div", { className: "flex-1 overflow-y-auto overflow-x-hidden pb-40 custom-scrollbar selection:bg-primary/20 dark:selection:bg-primary/30 min-h-0 h-full max-h-full", style: {
216
268
  backgroundColor: backgroundColors
217
269
  ? (darkMode && backgroundColors.dark
218
270
  ? backgroundColors.dark
219
271
  : backgroundColors.light)
220
- : '#faf9f6',
272
+ : '#ffffff',
221
273
  }, children: isPreviewMode ? (_jsx("div", { className: "mx-auto transition-all duration-500 max-w-[800px] px-6 py-6 w-full", children: _jsx(EmailPreview, { title: title, blocks: contentBlocks, siteId: siteId, locale: locale, metadata: metadata }) })) : (_jsx("div", { className: "mx-auto transition-all duration-500 max-w-[800px] px-6 py-6 w-full", children: _jsx("div", { className: "bg-gradient-to-b from-neutral-50 to-neutral-100 dark:from-neutral-900 dark:to-neutral-800 rounded-2xl p-6 border border-neutral-200 dark:border-neutral-700 shadow-xl", children: _jsxs("div", { className: "bg-white dark:bg-neutral-800 rounded-lg shadow-2xl overflow-hidden", children: [_jsxs("div", { className: "bg-white dark:bg-neutral-800 border-b border-neutral-200 dark:border-neutral-700", children: [_jsxs("div", { className: "px-4 py-2 flex items-center justify-between border-b border-neutral-100 dark:border-neutral-700", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-700 rounded", title: "Close", children: _jsx("svg", { className: "w-4 h-4 text-neutral-600 dark:text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }), _jsx("button", { className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-700 rounded", title: "Minimize", children: _jsx("svg", { className: "w-4 h-4 text-neutral-600 dark:text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M20 12H4" }) }) }), _jsx("button", { className: "p-1.5 hover:bg-neutral-100 dark:hover:bg-neutral-700 rounded", title: "Fullscreen", children: _jsx("svg", { className: "w-4 h-4 text-neutral-600 dark:text-neutral-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) }) })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsx("span", { className: "text-xs text-neutral-500 dark:text-neutral-400 font-medium", children: "Compose Email" }) })] }), _jsx("div", { className: "px-4 py-3 border-b border-neutral-100 dark:border-neutral-700", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "text-xs text-neutral-500 dark:text-neutral-400 font-medium w-16 flex-shrink-0", children: "To:" }), _jsx("input", { type: "text", value: "All Subscribers", readOnly: true, className: "flex-1 text-sm bg-transparent border-none outline-none text-neutral-700 dark:text-neutral-300 placeholder:text-neutral-400" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("label", { className: "text-xs text-neutral-500 dark:text-neutral-400 font-medium w-16 flex-shrink-0", children: "Subject:" }), _jsx("input", { type: "text", value: metadata?.subject || '', onChange: (e) => onMetadataChange?.({
222
274
  subject: e.target.value,
223
275
  previewText: metadata?.previewText,
@@ -225,33 +277,23 @@ export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, loca
225
277
  recipientFilter: metadata?.recipientFilter,
226
278
  }), placeholder: "Enter email subject...", className: "flex-1 text-sm bg-transparent border-none outline-none text-neutral-900 dark:text-neutral-100 placeholder:text-neutral-400 font-medium" })] })] }) })] }), _jsxs("div", { className: "bg-white dark:bg-neutral-800", style: {
227
279
  backgroundColor: '#ffffff',
228
- }, children: [(() => {
229
- // Get email config from window global (set by initNewsletterPlugin)
230
- let emailConfig = {};
231
- if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
232
- const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'];
233
- if (pluginProps?.emailConfig) {
234
- emailConfig = pluginProps.emailConfig;
235
- }
236
- }
237
- return emailConfig.logoUrl ? (_jsx("div", { style: {
238
- padding: '40px 0 20px 0',
239
- textAlign: 'center',
240
- backgroundColor: '#ffffff',
241
- display: 'flex',
242
- justifyContent: 'center',
243
- alignItems: 'center',
244
- }, children: _jsx("img", { src: emailConfig.logoUrl, alt: emailConfig.logoAlt || 'Logo', style: {
245
- width: '180px',
246
- height: 'auto',
247
- display: 'block',
248
- margin: '0 auto',
249
- } }) })) : null;
250
- })(), _jsxs("div", { className: "email-editor-content", style: {
280
+ }, children: [emailConfig?.logoUrl ? (_jsx("div", { style: {
281
+ padding: '40px 0 20px 0',
282
+ textAlign: 'center',
283
+ backgroundColor: '#ffffff',
284
+ display: 'flex',
285
+ justifyContent: 'center',
286
+ alignItems: 'center',
287
+ }, children: _jsx("img", { src: emailConfig.logoUrl, alt: emailConfig.logoAlt || 'Logo', style: {
288
+ width: '180px',
289
+ height: 'auto',
290
+ display: 'block',
291
+ margin: '0 auto',
292
+ } }) })) : null, _jsxs("div", { className: "email-editor-content", style: {
251
293
  fontFamily: "'Georgia', serif",
252
294
  color: '#1a2e26',
253
- lineHeight: '1.8',
254
- fontSize: '15px',
295
+ lineHeight: '1.625',
296
+ fontSize: '18px',
255
297
  padding: '0 50px 40px 50px',
256
298
  minHeight: '400px',
257
299
  backgroundColor: '#ffffff',
@@ -265,9 +307,11 @@ export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, loca
265
307
  };
266
308
  const slug = slugs[locale] || slugs.en;
267
309
  const unsubscribeUrl = `${baseUrl}${slug}?email=subscriber@example.com`;
268
- // Get unsubscribe text based on locale
269
- const isDutch = locale === 'nl';
270
- const unsubscribeText = isDutch ? 'Afmelden' : 'Unsubscribe';
310
+ // Get unsubscribe text (Priority: metadata manual override > global SMTP translation > hardcoded localized default)
311
+ const globalTranslations = emailConfig.unsubscribeTranslations || {};
312
+ const hardcodedDefaults = { en: 'Unsubscribe', nl: 'Afmelden', sv: 'Avanmälan' };
313
+ const defaultText = globalTranslations[locale] || hardcodedDefaults[locale] || hardcodedDefaults.en;
314
+ const unsubscribeText = metadata?.unsubscribeText || defaultText;
271
315
  return (_jsxs(_Fragment, { children: [_jsx("div", { style: {
272
316
  height: '1px',
273
317
  width: '40px',
@@ -282,26 +326,16 @@ export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, loca
282
326
  color: '#a1a1aa',
283
327
  textDecoration: 'none',
284
328
  }, onClick: (e) => e.preventDefault(), children: unsubscribeText }) })] }));
285
- })()] }), (() => {
286
- // Get email config from window global
287
- let emailConfig = {};
288
- if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
289
- const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'];
290
- if (pluginProps?.emailConfig) {
291
- emailConfig = pluginProps.emailConfig;
292
- }
293
- }
294
- return emailConfig.footerText ? (_jsx("div", { style: {
295
- padding: '40px 50px',
296
- textAlign: 'center',
297
- fontFamily: 'sans-serif',
298
- fontSize: '10px',
299
- color: '#a1a1aa',
300
- letterSpacing: '1px',
301
- borderTop: '1px solid #faf9f6',
302
- backgroundColor: '#ffffff',
303
- }, children: emailConfig.footerText })) : null;
304
- })()] })] }) }) })) }));
329
+ })()] }), emailConfig?.footerText ? (_jsx("div", { style: {
330
+ padding: '40px 50px',
331
+ textAlign: 'center',
332
+ fontFamily: 'sans-serif',
333
+ fontSize: '10px',
334
+ color: '#a1a1aa',
335
+ letterSpacing: '1px',
336
+ borderTop: '1px solid #faf9f6',
337
+ backgroundColor: '#ffffff',
338
+ }, children: emailConfig.footerText })) : null] })] }) }) })) }));
305
339
  }
306
340
  /**
307
341
  * Email Preview Component
@@ -309,17 +343,35 @@ export function EditorCanvas({ isPreviewMode, contentBlocks, title, siteId, loca
309
343
  * Matches the editor view structure for consistency
310
344
  */
311
345
  function EmailPreview({ title, blocks, siteId, locale, metadata }) {
346
+ const { emailConfig: contextEmailConfig, unsubscribeTranslations: contextUnsubscribeTranslations } = useEditor();
347
+ // SMTP settings take priority over client config
348
+ const emailConfig = useMemo(() => {
349
+ let smtpLogoUrl = '';
350
+ let smtpUnsubscribeTranslations = {};
351
+ if (typeof window !== 'undefined') {
352
+ const pluginProps = window.__JHITS_PLUGIN_PROPS__?.['plugin-newsletter'];
353
+ if (pluginProps?.emailConfig?.logoUrl) {
354
+ smtpLogoUrl = pluginProps.emailConfig.logoUrl;
355
+ }
356
+ if (pluginProps?.unsubscribeTranslations) {
357
+ smtpUnsubscribeTranslations = pluginProps.unsubscribeTranslations;
358
+ }
359
+ }
360
+ return {
361
+ ...contextEmailConfig,
362
+ logoUrl: smtpLogoUrl || contextEmailConfig?.logoUrl,
363
+ unsubscribeTranslations: {
364
+ en: 'Unsubscribe',
365
+ nl: 'Afmelden',
366
+ sv: 'Avanmälan',
367
+ ...contextUnsubscribeTranslations,
368
+ ...smtpUnsubscribeTranslations
369
+ }
370
+ };
371
+ }, [contextEmailConfig, contextUnsubscribeTranslations]);
312
372
  const [emailHtml, setEmailHtml] = useState('');
313
373
  const iframeRef = useRef(null);
314
374
  useEffect(() => {
315
- // Get email config from window global (set by initNewsletterPlugin)
316
- let emailConfig = {};
317
- if (typeof window !== 'undefined' && window.__JHITS_PLUGIN_PROPS__) {
318
- const pluginProps = window.__JHITS_PLUGIN_PROPS__['plugin-newsletter'];
319
- if (pluginProps?.emailConfig) {
320
- emailConfig = pluginProps.emailConfig;
321
- }
322
- }
323
375
  // Resolve image IDs to filenames before generating HTML
324
376
  const resolveImageBlocks = async () => {
325
377
  const resolvedBlocks = await Promise.all(blocks.map(async (block) => {
@@ -362,15 +414,21 @@ function EmailPreview({ title, blocks, siteId, locale, metadata }) {
362
414
  const slug = slugs[locale] || slugs.en;
363
415
  // Use placeholder email for preview
364
416
  const unsubscribeUrl = `${baseUrl}${slug}?email=subscriber@example.com`;
417
+ // Get unsubscribe text (Priority: metadata manual override > global SMTP translation > hardcoded localized default)
418
+ const globalTranslations = emailConfig.unsubscribeTranslations || {};
419
+ const hardcodedDefaults = { en: 'Unsubscribe', nl: 'Afmelden', sv: 'Avanmälan' };
420
+ const defaultText = globalTranslations[locale] || hardcodedDefaults[locale] || hardcodedDefaults.en;
421
+ const unsubscribeText = metadata?.unsubscribeText || defaultText;
365
422
  // Generate email HTML with resolved image blocks
366
423
  const html = generateNewsletterEmailHtml(resolvedBlocks, { subject: metadata?.subject || '', previewText: metadata?.previewText || '' }, {
367
424
  siteId,
368
425
  locale,
369
426
  baseUrl,
370
- logoUrl: emailConfig.logoUrl,
371
- logoAlt: emailConfig.logoAlt,
372
- footerText: emailConfig.footerText,
427
+ logoUrl: emailConfig?.logoUrl,
428
+ logoAlt: emailConfig?.logoAlt,
429
+ footerText: emailConfig?.footerText,
373
430
  unsubscribeUrl,
431
+ unsubscribeText,
374
432
  });
375
433
  setEmailHtml(html);
376
434
  // Update iframe content
@@ -385,7 +443,7 @@ function EmailPreview({ title, blocks, siteId, locale, metadata }) {
385
443
  }
386
444
  };
387
445
  resolveImageBlocks();
388
- }, [title, blocks, siteId, locale, metadata]);
446
+ }, [title, blocks, siteId, locale, metadata, emailConfig]);
389
447
  if (blocks.length === 0) {
390
448
  return (_jsx("div", { className: "bg-gradient-to-b from-neutral-50 to-neutral-100 dark:from-neutral-900 dark:to-neutral-800 rounded-2xl p-6 border border-neutral-200 dark:border-neutral-700 shadow-xl", children: _jsx("div", { className: "bg-white dark:bg-neutral-800 rounded-lg shadow-2xl overflow-hidden", children: _jsxs("div", { className: "text-center py-20 text-neutral-400 dark:text-neutral-500", children: [_jsx("p", { className: "text-sm", children: "No content blocks yet. Switch to Edit mode to add blocks." }), _jsx("p", { className: "text-xs mt-2 text-neutral-500 dark:text-neutral-600", children: "Email preview will appear here once you add blocks." })] }) }) }));
391
449
  }
@@ -393,5 +451,5 @@ function EmailPreview({ title, blocks, siteId, locale, metadata }) {
393
451
  minHeight: '500px',
394
452
  maxHeight: '900px',
395
453
  display: 'block',
396
- }, sandbox: "allow-same-origin" }) })] }) }) }));
454
+ }, sandbox: "allow-same-origin allow-scripts" }) })] }) }) }));
397
455
  }
@@ -8,6 +8,8 @@ export interface EditorSidebarProps {
8
8
  languages?: string[];
9
9
  currentLanguage?: string;
10
10
  onLanguageChange?: (language: string) => void;
11
+ globalUnsubscribeText?: string;
12
+ onGlobalUnsubscribeUpdate?: (text: string) => void;
11
13
  }
12
- export declare function EditorSidebar({ metadata, status, onMetadataUpdate, defaultLanguage, isWelcomeEmail, languages, currentLanguage, onLanguageChange, }: EditorSidebarProps): import("react/jsx-runtime").JSX.Element;
14
+ export declare function EditorSidebar({ metadata, status, onMetadataUpdate, defaultLanguage, isWelcomeEmail, languages, currentLanguage, onLanguageChange, globalUnsubscribeText, onGlobalUnsubscribeUpdate, }: EditorSidebarProps): import("react/jsx-runtime").JSX.Element;
13
15
  //# sourceMappingURL=EditorSidebar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EditorSidebar.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorSidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAED,wBAAgB,aAAa,CAAC,EAC1B,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,eAAsB,EACtB,cAAsB,EACtB,SAAkB,EAClB,eAAsB,EACtB,gBAAgB,GACnB,EAAE,kBAAkB,2CAgHpB"}
1
+ {"version":3,"file":"EditorSidebar.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/components/EditorSidebar.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,gBAAgB,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,kBAAkB,CAAC,KAAK,IAAI,CAAC;IAClE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,yBAAyB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED,wBAAgB,aAAa,CAAC,EAC1B,QAAQ,EACR,MAAM,EACN,gBAAgB,EAChB,eAAsB,EACtB,cAAsB,EACtB,SAAkB,EAClB,eAAsB,EACtB,gBAAgB,EAChB,qBAA0B,EAC1B,yBAAyB,GAC5B,EAAE,kBAAkB,2CAmKpB"}
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Mail, Users } from 'lucide-react';
4
- export function EditorSidebar({ metadata, status, onMetadataUpdate, defaultLanguage = 'en', isWelcomeEmail = false, languages = ['en'], currentLanguage = 'en', onLanguageChange, }) {
5
- return (_jsxs("div", { className: "p-8 w-80 min-w-0 max-w-full space-y-12 overflow-y-auto max-h-full", children: [_jsxs("section", { children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Mail, { size: 14, className: "text-neutral-500 dark:text-neutral-400" }), _jsx("label", { className: "text-[10px] uppercase tracking-[0.2em] text-neutral-500 dark:text-neutral-400 font-black", children: "Newsletter Settings" })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Email Subject" }), _jsx("input", { type: "text", value: metadata.subject || '', onChange: (e) => onMetadataUpdate({ subject: e.target.value }), placeholder: "Enter email subject", className: "w-full px-3 py-2 text-xs bg-dashboard-card border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text" }), _jsxs("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-1", children: [metadata.subject?.length || 0, " / 100 characters"] })] }), _jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Preview Text" }), _jsx("textarea", { value: metadata.previewText || '', onChange: (e) => onMetadataUpdate({ previewText: e.target.value }), placeholder: "Preview text shown in email clients", rows: 3, className: "w-full px-3 py-2 text-xs bg-dashboard-card border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text resize-none" }), _jsxs("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-1", children: [metadata.previewText?.length || 0, " / 150 characters"] })] })] })] }), _jsxs("section", { className: "pt-8 border-t border-neutral-200 dark:border-neutral-800", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Users, { size: 14, className: "text-neutral-500 dark:text-neutral-400" }), _jsx("label", { className: "text-[10px] uppercase tracking-[0.2em] text-neutral-500 dark:text-neutral-400 font-black", children: "Recipients" })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Filter Type" }), _jsxs("select", { value: metadata.recipientFilter?.type || 'all', onChange: (e) => onMetadataUpdate({
3
+ import { Mail, Users, Palette, Info } from 'lucide-react';
4
+ export function EditorSidebar({ metadata, status, onMetadataUpdate, defaultLanguage = 'en', isWelcomeEmail = false, languages = ['en'], currentLanguage = 'en', onLanguageChange, globalUnsubscribeText = '', onGlobalUnsubscribeUpdate, }) {
5
+ return (_jsxs("div", { className: "p-8 w-80 min-w-0 max-w-full space-y-12 overflow-y-auto max-h-full", children: [_jsxs("section", { children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Mail, { size: 14, className: "text-neutral-500 dark:text-neutral-400" }), _jsx("label", { className: "text-[10px] uppercase tracking-[0.2em] text-neutral-500 dark:text-neutral-400 font-black", children: "Campaign Settings" })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Email Subject" }), _jsx("input", { type: "text", value: metadata.subject || '', onChange: (e) => onMetadataUpdate({ subject: e.target.value }), placeholder: "Enter email subject", className: "w-full px-3 py-2 text-xs bg-dashboard-card border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text" }), _jsxs("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-1", children: [metadata.subject?.length || 0, " / 100 characters"] })] }), _jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Preview Text" }), _jsx("textarea", { value: metadata.previewText || '', onChange: (e) => onMetadataUpdate({ previewText: e.target.value }), placeholder: "Preview text shown in email clients", rows: 3, className: "w-full px-3 py-2 text-xs bg-dashboard-card border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text resize-none" }), _jsxs("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-1", children: [metadata.previewText?.length || 0, " / 150 characters"] })] })] })] }), _jsxs("section", { className: "pt-8 border-t border-neutral-200 dark:border-neutral-800", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Palette, { size: 14, className: "text-neutral-500 dark:text-neutral-400" }), _jsx("label", { className: "text-[10px] uppercase tracking-[0.2em] text-neutral-500 dark:text-neutral-400 font-black", children: "Global Branding" })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "bg-blue-50/50 dark:bg-blue-900/10 border border-blue-100 dark:border-blue-900/30 rounded-xl p-3 mb-4", children: _jsxs("div", { className: "flex gap-2 text-blue-600 dark:text-blue-400", children: [_jsx(Info, { size: 14, className: "flex-shrink-0 mt-0.5" }), _jsxs("p", { className: "text-[9px] leading-relaxed font-medium", children: ["Settings below apply to ", _jsx("span", { className: "font-bold", children: "ALL" }), " newsletters sent in ", _jsx("span", { className: "uppercase font-bold", children: currentLanguage }), "."] })] }) }), _jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Default Unsubscribe Text" }), _jsx("input", { type: "text", value: globalUnsubscribeText, onChange: (e) => onGlobalUnsubscribeUpdate?.(e.target.value), placeholder: "e.g. Unsubscribe from this list", className: "w-full px-3 py-2 text-xs bg-dashboard-card border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text italic" }), _jsx("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-2 leading-relaxed", children: "This updates your primary configuration for this language." })] }), _jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Local Campaign Override" }), _jsx("input", { type: "text", value: metadata.unsubscribeText || '', onChange: (e) => onMetadataUpdate({ unsubscribeText: e.target.value }), placeholder: "Optional override for this email only", className: "w-full px-3 py-2 text-xs bg-dashboard-bg border border-dashboard-border rounded-lg outline-none focus:border-primary transition-all text-dashboard-text" }), _jsx("p", { className: "text-[9px] text-neutral-400 dark:text-neutral-500 mt-1", children: "Only use this if you need a specific text for this single campaign." })] })] })] }), _jsxs("section", { className: "pt-8 border-t border-neutral-200 dark:border-neutral-800", children: [_jsxs("div", { className: "flex items-center gap-3 mb-6", children: [_jsx(Users, { size: 14, className: "text-neutral-500 dark:text-neutral-400" }), _jsx("label", { className: "text-[10px] uppercase tracking-[0.2em] text-neutral-500 dark:text-neutral-400 font-black", children: "Recipients" })] }), _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "text-[10px] text-neutral-500 dark:text-neutral-400 uppercase font-bold block mb-2", children: "Filter Type" }), _jsxs("select", { value: metadata.recipientFilter?.type || 'all', onChange: (e) => onMetadataUpdate({
6
6
  recipientFilter: {
7
7
  type: e.target.value,
8
8
  value: metadata.recipientFilter?.value,
@@ -1,2 +1,2 @@
1
- export declare function useRegisteredBlocks(): import("../../..").BlockTypeDefinition[];
1
+ export declare function useRegisteredBlocks(): import("../../../types/block").BlockTypeDefinition[];
2
2
  //# sourceMappingURL=useRegisteredBlocks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useRegisteredBlocks.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/useRegisteredBlocks.ts"],"names":[],"mappings":"AAGA,wBAAgB,mBAAmB,6CAkDlC"}
1
+ {"version":3,"file":"useRegisteredBlocks.d.ts","sourceRoot":"","sources":["../../../../src/views/CanvasEditor/hooks/useRegisteredBlocks.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,yDAUlC"}
@@ -1,46 +1,12 @@
1
1
  import { useState, useEffect } from 'react';
2
2
  import { blockRegistry } from '../../../registry/BlockRegistry';
3
+ import { useEditor } from '../../../state/EditorContext';
3
4
  export function useRegisteredBlocks() {
4
- const [registeredBlocks, setRegisteredBlocks] = useState(() => {
5
- const initial = blockRegistry.getAll();
6
- return initial;
7
- });
8
- // Watch for registry changes and update state
5
+ const { registeredBlockTypes } = useEditor();
6
+ const [registeredBlocks, setRegisteredBlocks] = useState(() => blockRegistry.getAll());
7
+ // Update local state whenever registeredBlockTypes changes in context
9
8
  useEffect(() => {
10
- // Check immediately
11
- const checkBlocks = () => {
12
- const currentBlocks = blockRegistry.getAll();
13
- const hasChanged = currentBlocks.length !== registeredBlocks.length ||
14
- currentBlocks.some((b, i) => b.type !== registeredBlocks[i]?.type) ||
15
- registeredBlocks.some((b, i) => b.type !== currentBlocks[i]?.type);
16
- if (hasChanged) {
17
- setRegisteredBlocks([...currentBlocks]);
18
- }
19
- };
20
- // Initial check
21
- checkBlocks();
22
- // Poll for registry changes (blocks are registered asynchronously in useEffect)
23
- let pollCount = 0;
24
- const interval = setInterval(() => {
25
- pollCount++;
26
- checkBlocks();
27
- // Stop polling after 5 seconds (25 checks at 200ms)
28
- if (pollCount > 25) {
29
- clearInterval(interval);
30
- }
31
- }, 200);
32
- // Also check after delays to catch initial registrations
33
- const timeouts = [
34
- setTimeout(checkBlocks, 50),
35
- setTimeout(checkBlocks, 100),
36
- setTimeout(checkBlocks, 300),
37
- setTimeout(checkBlocks, 500),
38
- setTimeout(checkBlocks, 1000),
39
- ];
40
- return () => {
41
- clearInterval(interval);
42
- timeouts.forEach(clearTimeout);
43
- };
44
- }, [registeredBlocks.length]);
9
+ setRegisteredBlocks(blockRegistry.getAll());
10
+ }, [registeredBlockTypes]);
45
11
  return registeredBlocks;
46
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NewsletterManager.d.ts","sourceRoot":"","sources":["../../src/views/NewsletterManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,WAAW,0BAA0B;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,2CAydnF"}
1
+ {"version":3,"file":"NewsletterManager.d.ts","sourceRoot":"","sources":["../../src/views/NewsletterManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,0BAA0B;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAiBD,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,0BAA0B,2CAqnBnF"}