strapi-plugin-magic-mail 1.0.3 → 1.0.5

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.
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useRef, lazy, Suspense } from 'react';
1
+ import React, { useState, useEffect, useRef } from 'react';
2
2
  import { useFetchClient, useNotification } from '@strapi/strapi/admin';
3
3
  import { useNavigate, useLocation } from 'react-router-dom';
4
4
  import { useAuthRefresh } from '../../hooks/useAuthRefresh';
@@ -26,6 +26,7 @@ import {
26
26
  CodeBracketIcon,
27
27
  } from '@heroicons/react/24/outline';
28
28
  import { useLicense } from '../../hooks/useLicense';
29
+ import EmailEditor from 'react-email-editor';
29
30
 
30
31
  // Standard Email Template for Core Emails (when no design exists)
31
32
  const STANDARD_EMAIL_TEMPLATE = {
@@ -107,14 +108,6 @@ const STANDARD_EMAIL_TEMPLATE = {
107
108
  schemaVersion: 6,
108
109
  };
109
110
 
110
- // Dynamic import for Email Editor (500KB)
111
- const EmailEditor = lazy(async () => {
112
- const module = await import('react-email-editor');
113
- return {
114
- default: module.default || module.EmailEditor,
115
- };
116
- });
117
-
118
111
  // Styled components
119
112
  const Container = styled.div`
120
113
  min-height: 100vh;
@@ -246,6 +239,16 @@ const LoadingContainer = styled.div`
246
239
  align-items: center;
247
240
  `;
248
241
 
242
+ const EditorCanvas = styled.div`
243
+ min-height: calc(100vh - 240px);
244
+ `;
245
+
246
+ const DesignerLoadingContainer = styled(LoadingContainer)`
247
+ width: 100%;
248
+ min-height: calc(100vh - 240px);
249
+ padding: 40px 20px;
250
+ `;
251
+
249
252
  const HiddenInput = styled.input`
250
253
  display: none;
251
254
  `;
@@ -586,6 +589,7 @@ const EditorPage = () => {
586
589
  const [loading, setLoading] = useState(!isNewTemplate && !isCoreEmail);
587
590
  const [saving, setSaving] = useState(false);
588
591
  const [activeTab, setActiveTab] = useState('html');
592
+ const [editorLoaded, setEditorLoaded] = useState(false);
589
593
 
590
594
  const [templateData, setTemplateData] = useState({
591
595
  templateReferenceId: '',
@@ -938,6 +942,7 @@ const EditorPage = () => {
938
942
  };
939
943
 
940
944
  const onEditorReady = () => {
945
+ setEditorLoaded(true);
941
946
  if (templateData.design && emailEditorRef.current?.editor) {
942
947
  setTimeout(() => {
943
948
  emailEditorRef.current.editor.loadDesign(templateData.design);
@@ -1102,12 +1107,16 @@ const EditorPage = () => {
1102
1107
 
1103
1108
  <StyledTabsContent value="html">
1104
1109
  <TabContentWrapper>
1105
- <Suspense
1106
- fallback={
1107
- <LoadingContainer>
1108
- <Loader>Loading Email Designer...</Loader>
1109
- </LoadingContainer>
1110
- }
1110
+ {!editorLoaded && (
1111
+ <DesignerLoadingContainer>
1112
+ <Loader>Loading Email Designer...</Loader>
1113
+ </DesignerLoadingContainer>
1114
+ )}
1115
+ <EditorCanvas
1116
+ style={{
1117
+ visibility: editorLoaded ? 'visible' : 'hidden',
1118
+ pointerEvents: editorLoaded ? 'auto' : 'none',
1119
+ }}
1111
1120
  >
1112
1121
  <EmailEditor
1113
1122
  ref={emailEditorRef}
@@ -1293,7 +1302,7 @@ const EditorPage = () => {
1293
1302
  }
1294
1303
  }}
1295
1304
  />
1296
- </Suspense>
1305
+ </EditorCanvas>
1297
1306
  </TabContentWrapper>
1298
1307
  </StyledTabsContent>
1299
1308
 
@@ -1,26 +1,4 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (let key of __getOwnPropNames(from))
11
- if (!__hasOwnProp.call(to, key) && key !== except)
12
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
- }
14
- return to;
15
- };
16
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
- // If the importer is in node compatibility mode or this is not an ESM
18
- // file that has been converted to a CommonJS file using a Babel-
19
- // compatible transform (i.e. "__esModule" has not been set), then set
20
- // "default" to the CommonJS "module.exports" for node compatibility.
21
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
- mod
23
- ));
24
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
3
  const jsxRuntime = require("react/jsx-runtime");
26
4
  const React = require("react");
@@ -30,9 +8,11 @@ const outline = require("@heroicons/react/24/outline");
30
8
  const admin = require("@strapi/strapi/admin");
31
9
  const styled = require("styled-components");
32
10
  const icons = require("@strapi/icons");
11
+ const EmailEditor = require("react-email-editor");
33
12
  const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
34
13
  const React__default = /* @__PURE__ */ _interopDefault(React);
35
14
  const styled__default = /* @__PURE__ */ _interopDefault(styled);
15
+ const EmailEditor__default = /* @__PURE__ */ _interopDefault(EmailEditor);
36
16
  const useAuthRefresh = () => {
37
17
  const { get } = admin.useFetchClient();
38
18
  const intervalRef = React.useRef(null);
@@ -5422,12 +5402,6 @@ const STANDARD_EMAIL_TEMPLATE = {
5422
5402
  },
5423
5403
  schemaVersion: 6
5424
5404
  };
5425
- const EmailEditor = React.lazy(async () => {
5426
- const module2 = await import("react-email-editor");
5427
- return {
5428
- default: module2.default || module2.EmailEditor
5429
- };
5430
- });
5431
5405
  const Container$1 = styled__default.default.div`
5432
5406
  min-height: 100vh;
5433
5407
  display: flex;
@@ -5542,6 +5516,14 @@ const LoadingContainer = styled__default.default.div`
5542
5516
  justify-content: center;
5543
5517
  align-items: center;
5544
5518
  `;
5519
+ const EditorCanvas = styled__default.default.div`
5520
+ min-height: calc(100vh - 240px);
5521
+ `;
5522
+ const DesignerLoadingContainer = styled__default.default(LoadingContainer)`
5523
+ width: 100%;
5524
+ min-height: calc(100vh - 240px);
5525
+ padding: 40px 20px;
5526
+ `;
5545
5527
  const HiddenInput = styled__default.default.input`
5546
5528
  display: none;
5547
5529
  `;
@@ -5855,6 +5837,7 @@ const EditorPage = () => {
5855
5837
  const [loading, setLoading] = React.useState(!isNewTemplate && !isCoreEmail);
5856
5838
  const [saving, setSaving] = React.useState(false);
5857
5839
  const [activeTab, setActiveTab] = React.useState("html");
5840
+ const [editorLoaded, setEditorLoaded] = React.useState(false);
5858
5841
  const [templateData, setTemplateData] = React.useState({
5859
5842
  templateReferenceId: "",
5860
5843
  name: "",
@@ -6137,6 +6120,7 @@ const EditorPage = () => {
6137
6120
  reader.readAsText(file);
6138
6121
  };
6139
6122
  const onEditorReady = () => {
6123
+ setEditorLoaded(true);
6140
6124
  if (templateData.design && emailEditorRef.current?.editor) {
6141
6125
  setTimeout(() => {
6142
6126
  emailEditorRef.current.editor.loadDesign(templateData.design);
@@ -6253,192 +6237,198 @@ const EditorPage = () => {
6253
6237
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "html", children: "✨ Visual Designer" }),
6254
6238
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tabs.Trigger, { value: "text", children: "📝 Plain Text" })
6255
6239
  ] }) }),
6256
- /* @__PURE__ */ jsxRuntime.jsx(StyledTabsContent, { value: "html", children: /* @__PURE__ */ jsxRuntime.jsx(TabContentWrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
6257
- React.Suspense,
6258
- {
6259
- fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: "Loading Email Designer..." }) }),
6260
- children: /* @__PURE__ */ jsxRuntime.jsx(
6261
- EmailEditor,
6262
- {
6263
- ref: emailEditorRef,
6264
- onReady: onEditorReady,
6265
- minHeight: "calc(100vh - 240px)",
6266
- options: {
6267
- // Display mode
6268
- displayMode: "email",
6269
- locale: "en",
6270
- projectId: 1,
6271
- // Required for some features
6272
- // Merge Tags Config
6273
- mergeTagsConfig: {
6274
- autocompleteTriggerChar: "@",
6275
- sort: false,
6276
- delimiter: ["{{", "}}"]
6277
- },
6278
- // Appearance
6279
- appearance: {
6280
- theme: "modern_light",
6281
- panels: {
6282
- tools: { dock: "left" }
6283
- }
6284
- },
6285
- // Features - Enable responsive preview
6286
- features: {
6287
- preview: true,
6288
- previewInBrowser: true,
6289
- textEditor: {
6290
- enabled: true,
6291
- spellChecker: true,
6292
- tables: true,
6293
- cleanPaste: true
6294
- }
6295
- },
6296
- // Fonts
6297
- fonts: {
6298
- showDefaultFonts: true,
6299
- customFonts: [
6300
- {
6301
- label: "Inter",
6302
- value: "'Inter', sans-serif",
6303
- url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
6240
+ /* @__PURE__ */ jsxRuntime.jsx(StyledTabsContent, { value: "html", children: /* @__PURE__ */ jsxRuntime.jsxs(TabContentWrapper, { children: [
6241
+ !editorLoaded && /* @__PURE__ */ jsxRuntime.jsx(DesignerLoadingContainer, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Loader, { children: "Loading Email Designer..." }) }),
6242
+ /* @__PURE__ */ jsxRuntime.jsx(
6243
+ EditorCanvas,
6244
+ {
6245
+ style: {
6246
+ visibility: editorLoaded ? "visible" : "hidden",
6247
+ pointerEvents: editorLoaded ? "auto" : "none"
6248
+ },
6249
+ children: /* @__PURE__ */ jsxRuntime.jsx(
6250
+ EmailEditor__default.default,
6251
+ {
6252
+ ref: emailEditorRef,
6253
+ onReady: onEditorReady,
6254
+ minHeight: "calc(100vh - 240px)",
6255
+ options: {
6256
+ // Display mode
6257
+ displayMode: "email",
6258
+ locale: "en",
6259
+ projectId: 1,
6260
+ // Required for some features
6261
+ // Merge Tags Config
6262
+ mergeTagsConfig: {
6263
+ autocompleteTriggerChar: "@",
6264
+ sort: false,
6265
+ delimiter: ["{{", "}}"]
6266
+ },
6267
+ // Appearance
6268
+ appearance: {
6269
+ theme: "modern_light",
6270
+ panels: {
6271
+ tools: { dock: "left" }
6304
6272
  }
6305
- ]
6306
- },
6307
- // Tools configuration - minimal, let Unlayer show all
6308
- tools: {
6309
- image: {
6310
- properties: {
6311
- src: {
6312
- value: {
6313
- url: "https://picsum.photos/600/350"
6314
- }
6315
- }
6273
+ },
6274
+ // Features - Enable responsive preview
6275
+ features: {
6276
+ preview: true,
6277
+ previewInBrowser: true,
6278
+ textEditor: {
6279
+ enabled: true,
6280
+ spellChecker: true,
6281
+ tables: true,
6282
+ cleanPaste: true
6316
6283
  }
6317
- }
6318
- },
6319
- // Merge Tags with extended support
6320
- mergeTags: {
6321
- user: {
6322
- name: "User",
6323
- mergeTags: {
6324
- firstName: {
6325
- name: "First Name",
6326
- value: "{{user.firstName}}",
6327
- sample: "John"
6328
- },
6329
- lastName: {
6330
- name: "Last Name",
6331
- value: "{{user.lastName}}",
6332
- sample: "Doe"
6333
- },
6334
- email: {
6335
- name: "Email",
6336
- value: "{{user.email}}",
6337
- sample: "john@example.com"
6338
- },
6339
- username: {
6340
- name: "Username",
6341
- value: "{{user.username}}",
6342
- sample: "johndoe"
6284
+ },
6285
+ // Fonts
6286
+ fonts: {
6287
+ showDefaultFonts: true,
6288
+ customFonts: [
6289
+ {
6290
+ label: "Inter",
6291
+ value: "'Inter', sans-serif",
6292
+ url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
6343
6293
  }
6344
- }
6294
+ ]
6345
6295
  },
6346
- company: {
6347
- name: "Company",
6348
- mergeTags: {
6349
- name: {
6350
- name: "Name",
6351
- value: "{{company.name}}",
6352
- sample: "ACME Corp"
6353
- },
6354
- url: {
6355
- name: "Website",
6356
- value: "{{company.url}}",
6357
- sample: "https://acme.com"
6358
- },
6359
- address: {
6360
- name: "Address",
6361
- value: "{{company.address}}",
6362
- sample: "123 Main St, City"
6296
+ // Tools configuration - minimal, let Unlayer show all
6297
+ tools: {
6298
+ image: {
6299
+ properties: {
6300
+ src: {
6301
+ value: {
6302
+ url: "https://picsum.photos/600/350"
6303
+ }
6304
+ }
6363
6305
  }
6364
6306
  }
6365
6307
  },
6366
- order: {
6367
- name: "Order",
6368
- mergeTags: {
6369
- number: {
6370
- name: "Number",
6371
- value: "{{order.number}}",
6372
- sample: "#12345"
6373
- },
6374
- total: {
6375
- name: "Total",
6376
- value: "{{order.total}}",
6377
- sample: "$199.99"
6378
- },
6379
- date: {
6380
- name: "Date",
6381
- value: "{{order.date}}",
6382
- sample: "2024-01-15"
6383
- },
6384
- status: {
6385
- name: "Status",
6386
- value: "{{order.status}}",
6387
- sample: "Shipped"
6308
+ // Merge Tags with extended support
6309
+ mergeTags: {
6310
+ user: {
6311
+ name: "User",
6312
+ mergeTags: {
6313
+ firstName: {
6314
+ name: "First Name",
6315
+ value: "{{user.firstName}}",
6316
+ sample: "John"
6317
+ },
6318
+ lastName: {
6319
+ name: "Last Name",
6320
+ value: "{{user.lastName}}",
6321
+ sample: "Doe"
6322
+ },
6323
+ email: {
6324
+ name: "Email",
6325
+ value: "{{user.email}}",
6326
+ sample: "john@example.com"
6327
+ },
6328
+ username: {
6329
+ name: "Username",
6330
+ value: "{{user.username}}",
6331
+ sample: "johndoe"
6332
+ }
6333
+ }
6334
+ },
6335
+ company: {
6336
+ name: "Company",
6337
+ mergeTags: {
6338
+ name: {
6339
+ name: "Name",
6340
+ value: "{{company.name}}",
6341
+ sample: "ACME Corp"
6342
+ },
6343
+ url: {
6344
+ name: "Website",
6345
+ value: "{{company.url}}",
6346
+ sample: "https://acme.com"
6347
+ },
6348
+ address: {
6349
+ name: "Address",
6350
+ value: "{{company.address}}",
6351
+ sample: "123 Main St, City"
6352
+ }
6353
+ }
6354
+ },
6355
+ order: {
6356
+ name: "Order",
6357
+ mergeTags: {
6358
+ number: {
6359
+ name: "Number",
6360
+ value: "{{order.number}}",
6361
+ sample: "#12345"
6362
+ },
6363
+ total: {
6364
+ name: "Total",
6365
+ value: "{{order.total}}",
6366
+ sample: "$199.99"
6367
+ },
6368
+ date: {
6369
+ name: "Date",
6370
+ value: "{{order.date}}",
6371
+ sample: "2024-01-15"
6372
+ },
6373
+ status: {
6374
+ name: "Status",
6375
+ value: "{{order.status}}",
6376
+ sample: "Shipped"
6377
+ }
6378
+ }
6379
+ },
6380
+ system: {
6381
+ name: "System",
6382
+ mergeTags: {
6383
+ date: {
6384
+ name: "Current Date",
6385
+ value: "{{system.date}}",
6386
+ sample: (/* @__PURE__ */ new Date()).toLocaleDateString()
6387
+ },
6388
+ year: {
6389
+ name: "Current Year",
6390
+ value: "{{system.year}}",
6391
+ sample: (/* @__PURE__ */ new Date()).getFullYear().toString()
6392
+ },
6393
+ unsubscribe: {
6394
+ name: "Unsubscribe Link",
6395
+ value: "{{system.unsubscribe}}",
6396
+ sample: "https://example.com/unsubscribe"
6397
+ }
6388
6398
  }
6389
6399
  }
6390
6400
  },
6391
- system: {
6392
- name: "System",
6393
- mergeTags: {
6394
- date: {
6395
- name: "Current Date",
6396
- value: "{{system.date}}",
6397
- sample: (/* @__PURE__ */ new Date()).toLocaleDateString()
6398
- },
6399
- year: {
6400
- name: "Current Year",
6401
- value: "{{system.year}}",
6402
- sample: (/* @__PURE__ */ new Date()).getFullYear().toString()
6403
- },
6404
- unsubscribe: {
6405
- name: "Unsubscribe Link",
6406
- value: "{{system.unsubscribe}}",
6407
- sample: "https://example.com/unsubscribe"
6408
- }
6401
+ // Special links
6402
+ specialLinks: {
6403
+ unsubscribe: {
6404
+ enabled: true,
6405
+ text: "Unsubscribe",
6406
+ href: "{{system.unsubscribe}}"
6407
+ },
6408
+ webview: {
6409
+ enabled: true,
6410
+ text: "View in browser",
6411
+ href: "{{system.webview}}"
6409
6412
  }
6410
- }
6411
- },
6412
- // Special links
6413
- specialLinks: {
6414
- unsubscribe: {
6415
- enabled: true,
6416
- text: "Unsubscribe",
6417
- href: "{{system.unsubscribe}}"
6418
6413
  },
6419
- webview: {
6414
+ // Custom CSS
6415
+ customCSS: [
6416
+ ".blockbuilder-content-email { font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif; }"
6417
+ ],
6418
+ // Validation
6419
+ validator: {
6420
6420
  enabled: true,
6421
- text: "View in browser",
6422
- href: "{{system.webview}}"
6423
- }
6424
- },
6425
- // Custom CSS
6426
- customCSS: [
6427
- ".blockbuilder-content-email { font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif; }"
6428
- ],
6429
- // Validation
6430
- validator: {
6431
- enabled: true,
6432
- rules: {
6433
- maxImageSize: 1024 * 1024
6434
- // 1MB
6421
+ rules: {
6422
+ maxImageSize: 1024 * 1024
6423
+ // 1MB
6424
+ }
6435
6425
  }
6436
6426
  }
6437
6427
  }
6438
- }
6439
- )
6440
- }
6441
- ) }) }),
6428
+ )
6429
+ }
6430
+ )
6431
+ ] }) }),
6442
6432
  /* @__PURE__ */ jsxRuntime.jsx(StyledTabsContent, { value: "text", children: /* @__PURE__ */ jsxRuntime.jsx(TextTabContent, { children: /* @__PURE__ */ jsxRuntime.jsx(
6443
6433
  designSystem.Textarea,
6444
6434
  {
@@ -1,11 +1,12 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import React, { useRef, useEffect, useState, Suspense, lazy } from "react";
2
+ import React, { useRef, useEffect, useState } from "react";
3
3
  import { useNavigate, useLocation } from "react-router-dom";
4
4
  import { Modal, Typography, Flex, Box, Field, TextInput, Alert, Textarea, NumberInput, Divider, Toggle, Badge, Button, Loader, SingleSelect, SingleSelectOption, Thead, Tr, Th, Tbody, Td, Table, Tabs } from "@strapi/design-system";
5
5
  import { EnvelopeIcon, ServerIcon, SparklesIcon, PlusIcon, PencilIcon, PlayIcon, TrashIcon, MagnifyingGlassIcon, FunnelIcon, CheckIcon, Cog6ToothIcon, DocumentTextIcon, ChartBarIcon, BoltIcon, CheckCircleIcon, ArrowUpTrayIcon, ArrowDownTrayIcon, DocumentArrowDownIcon, CodeBracketIcon, DocumentDuplicateIcon, PaperAirplaneIcon, ClipboardDocumentIcon, ArrowLeftIcon, ClockIcon, XMarkIcon, ArrowUturnLeftIcon, EnvelopeOpenIcon, CursorArrowRaysIcon, ExclamationTriangleIcon, XCircleIcon, KeyIcon } from "@heroicons/react/24/outline";
6
6
  import { useFetchClient, useNotification } from "@strapi/strapi/admin";
7
7
  import styled, { css, keyframes } from "styled-components";
8
8
  import { Star, Mail, Server, Lock, Cog, Check, Cloud, Key, ArrowLeft, ArrowRight } from "@strapi/icons";
9
+ import EmailEditor from "react-email-editor";
9
10
  const useAuthRefresh = () => {
10
11
  const { get } = useFetchClient();
11
12
  const intervalRef = useRef(null);
@@ -5395,12 +5396,6 @@ const STANDARD_EMAIL_TEMPLATE = {
5395
5396
  },
5396
5397
  schemaVersion: 6
5397
5398
  };
5398
- const EmailEditor = lazy(async () => {
5399
- const module = await import("react-email-editor");
5400
- return {
5401
- default: module.default || module.EmailEditor
5402
- };
5403
- });
5404
5399
  const Container$1 = styled.div`
5405
5400
  min-height: 100vh;
5406
5401
  display: flex;
@@ -5515,6 +5510,14 @@ const LoadingContainer = styled.div`
5515
5510
  justify-content: center;
5516
5511
  align-items: center;
5517
5512
  `;
5513
+ const EditorCanvas = styled.div`
5514
+ min-height: calc(100vh - 240px);
5515
+ `;
5516
+ const DesignerLoadingContainer = styled(LoadingContainer)`
5517
+ width: 100%;
5518
+ min-height: calc(100vh - 240px);
5519
+ padding: 40px 20px;
5520
+ `;
5518
5521
  const HiddenInput = styled.input`
5519
5522
  display: none;
5520
5523
  `;
@@ -5828,6 +5831,7 @@ const EditorPage = () => {
5828
5831
  const [loading, setLoading] = useState(!isNewTemplate && !isCoreEmail);
5829
5832
  const [saving, setSaving] = useState(false);
5830
5833
  const [activeTab, setActiveTab] = useState("html");
5834
+ const [editorLoaded, setEditorLoaded] = useState(false);
5831
5835
  const [templateData, setTemplateData] = useState({
5832
5836
  templateReferenceId: "",
5833
5837
  name: "",
@@ -6110,6 +6114,7 @@ const EditorPage = () => {
6110
6114
  reader.readAsText(file);
6111
6115
  };
6112
6116
  const onEditorReady = () => {
6117
+ setEditorLoaded(true);
6113
6118
  if (templateData.design && emailEditorRef.current?.editor) {
6114
6119
  setTimeout(() => {
6115
6120
  emailEditorRef.current.editor.loadDesign(templateData.design);
@@ -6226,192 +6231,198 @@ const EditorPage = () => {
6226
6231
  /* @__PURE__ */ jsx(Tabs.Trigger, { value: "html", children: "✨ Visual Designer" }),
6227
6232
  /* @__PURE__ */ jsx(Tabs.Trigger, { value: "text", children: "📝 Plain Text" })
6228
6233
  ] }) }),
6229
- /* @__PURE__ */ jsx(StyledTabsContent, { value: "html", children: /* @__PURE__ */ jsx(TabContentWrapper, { children: /* @__PURE__ */ jsx(
6230
- Suspense,
6231
- {
6232
- fallback: /* @__PURE__ */ jsx(LoadingContainer, { children: /* @__PURE__ */ jsx(Loader, { children: "Loading Email Designer..." }) }),
6233
- children: /* @__PURE__ */ jsx(
6234
- EmailEditor,
6235
- {
6236
- ref: emailEditorRef,
6237
- onReady: onEditorReady,
6238
- minHeight: "calc(100vh - 240px)",
6239
- options: {
6240
- // Display mode
6241
- displayMode: "email",
6242
- locale: "en",
6243
- projectId: 1,
6244
- // Required for some features
6245
- // Merge Tags Config
6246
- mergeTagsConfig: {
6247
- autocompleteTriggerChar: "@",
6248
- sort: false,
6249
- delimiter: ["{{", "}}"]
6250
- },
6251
- // Appearance
6252
- appearance: {
6253
- theme: "modern_light",
6254
- panels: {
6255
- tools: { dock: "left" }
6256
- }
6257
- },
6258
- // Features - Enable responsive preview
6259
- features: {
6260
- preview: true,
6261
- previewInBrowser: true,
6262
- textEditor: {
6263
- enabled: true,
6264
- spellChecker: true,
6265
- tables: true,
6266
- cleanPaste: true
6267
- }
6268
- },
6269
- // Fonts
6270
- fonts: {
6271
- showDefaultFonts: true,
6272
- customFonts: [
6273
- {
6274
- label: "Inter",
6275
- value: "'Inter', sans-serif",
6276
- url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
6234
+ /* @__PURE__ */ jsx(StyledTabsContent, { value: "html", children: /* @__PURE__ */ jsxs(TabContentWrapper, { children: [
6235
+ !editorLoaded && /* @__PURE__ */ jsx(DesignerLoadingContainer, { children: /* @__PURE__ */ jsx(Loader, { children: "Loading Email Designer..." }) }),
6236
+ /* @__PURE__ */ jsx(
6237
+ EditorCanvas,
6238
+ {
6239
+ style: {
6240
+ visibility: editorLoaded ? "visible" : "hidden",
6241
+ pointerEvents: editorLoaded ? "auto" : "none"
6242
+ },
6243
+ children: /* @__PURE__ */ jsx(
6244
+ EmailEditor,
6245
+ {
6246
+ ref: emailEditorRef,
6247
+ onReady: onEditorReady,
6248
+ minHeight: "calc(100vh - 240px)",
6249
+ options: {
6250
+ // Display mode
6251
+ displayMode: "email",
6252
+ locale: "en",
6253
+ projectId: 1,
6254
+ // Required for some features
6255
+ // Merge Tags Config
6256
+ mergeTagsConfig: {
6257
+ autocompleteTriggerChar: "@",
6258
+ sort: false,
6259
+ delimiter: ["{{", "}}"]
6260
+ },
6261
+ // Appearance
6262
+ appearance: {
6263
+ theme: "modern_light",
6264
+ panels: {
6265
+ tools: { dock: "left" }
6277
6266
  }
6278
- ]
6279
- },
6280
- // Tools configuration - minimal, let Unlayer show all
6281
- tools: {
6282
- image: {
6283
- properties: {
6284
- src: {
6285
- value: {
6286
- url: "https://picsum.photos/600/350"
6287
- }
6288
- }
6267
+ },
6268
+ // Features - Enable responsive preview
6269
+ features: {
6270
+ preview: true,
6271
+ previewInBrowser: true,
6272
+ textEditor: {
6273
+ enabled: true,
6274
+ spellChecker: true,
6275
+ tables: true,
6276
+ cleanPaste: true
6289
6277
  }
6290
- }
6291
- },
6292
- // Merge Tags with extended support
6293
- mergeTags: {
6294
- user: {
6295
- name: "User",
6296
- mergeTags: {
6297
- firstName: {
6298
- name: "First Name",
6299
- value: "{{user.firstName}}",
6300
- sample: "John"
6301
- },
6302
- lastName: {
6303
- name: "Last Name",
6304
- value: "{{user.lastName}}",
6305
- sample: "Doe"
6306
- },
6307
- email: {
6308
- name: "Email",
6309
- value: "{{user.email}}",
6310
- sample: "john@example.com"
6311
- },
6312
- username: {
6313
- name: "Username",
6314
- value: "{{user.username}}",
6315
- sample: "johndoe"
6278
+ },
6279
+ // Fonts
6280
+ fonts: {
6281
+ showDefaultFonts: true,
6282
+ customFonts: [
6283
+ {
6284
+ label: "Inter",
6285
+ value: "'Inter', sans-serif",
6286
+ url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
6316
6287
  }
6317
- }
6288
+ ]
6318
6289
  },
6319
- company: {
6320
- name: "Company",
6321
- mergeTags: {
6322
- name: {
6323
- name: "Name",
6324
- value: "{{company.name}}",
6325
- sample: "ACME Corp"
6326
- },
6327
- url: {
6328
- name: "Website",
6329
- value: "{{company.url}}",
6330
- sample: "https://acme.com"
6331
- },
6332
- address: {
6333
- name: "Address",
6334
- value: "{{company.address}}",
6335
- sample: "123 Main St, City"
6290
+ // Tools configuration - minimal, let Unlayer show all
6291
+ tools: {
6292
+ image: {
6293
+ properties: {
6294
+ src: {
6295
+ value: {
6296
+ url: "https://picsum.photos/600/350"
6297
+ }
6298
+ }
6336
6299
  }
6337
6300
  }
6338
6301
  },
6339
- order: {
6340
- name: "Order",
6341
- mergeTags: {
6342
- number: {
6343
- name: "Number",
6344
- value: "{{order.number}}",
6345
- sample: "#12345"
6346
- },
6347
- total: {
6348
- name: "Total",
6349
- value: "{{order.total}}",
6350
- sample: "$199.99"
6351
- },
6352
- date: {
6353
- name: "Date",
6354
- value: "{{order.date}}",
6355
- sample: "2024-01-15"
6356
- },
6357
- status: {
6358
- name: "Status",
6359
- value: "{{order.status}}",
6360
- sample: "Shipped"
6302
+ // Merge Tags with extended support
6303
+ mergeTags: {
6304
+ user: {
6305
+ name: "User",
6306
+ mergeTags: {
6307
+ firstName: {
6308
+ name: "First Name",
6309
+ value: "{{user.firstName}}",
6310
+ sample: "John"
6311
+ },
6312
+ lastName: {
6313
+ name: "Last Name",
6314
+ value: "{{user.lastName}}",
6315
+ sample: "Doe"
6316
+ },
6317
+ email: {
6318
+ name: "Email",
6319
+ value: "{{user.email}}",
6320
+ sample: "john@example.com"
6321
+ },
6322
+ username: {
6323
+ name: "Username",
6324
+ value: "{{user.username}}",
6325
+ sample: "johndoe"
6326
+ }
6327
+ }
6328
+ },
6329
+ company: {
6330
+ name: "Company",
6331
+ mergeTags: {
6332
+ name: {
6333
+ name: "Name",
6334
+ value: "{{company.name}}",
6335
+ sample: "ACME Corp"
6336
+ },
6337
+ url: {
6338
+ name: "Website",
6339
+ value: "{{company.url}}",
6340
+ sample: "https://acme.com"
6341
+ },
6342
+ address: {
6343
+ name: "Address",
6344
+ value: "{{company.address}}",
6345
+ sample: "123 Main St, City"
6346
+ }
6347
+ }
6348
+ },
6349
+ order: {
6350
+ name: "Order",
6351
+ mergeTags: {
6352
+ number: {
6353
+ name: "Number",
6354
+ value: "{{order.number}}",
6355
+ sample: "#12345"
6356
+ },
6357
+ total: {
6358
+ name: "Total",
6359
+ value: "{{order.total}}",
6360
+ sample: "$199.99"
6361
+ },
6362
+ date: {
6363
+ name: "Date",
6364
+ value: "{{order.date}}",
6365
+ sample: "2024-01-15"
6366
+ },
6367
+ status: {
6368
+ name: "Status",
6369
+ value: "{{order.status}}",
6370
+ sample: "Shipped"
6371
+ }
6372
+ }
6373
+ },
6374
+ system: {
6375
+ name: "System",
6376
+ mergeTags: {
6377
+ date: {
6378
+ name: "Current Date",
6379
+ value: "{{system.date}}",
6380
+ sample: (/* @__PURE__ */ new Date()).toLocaleDateString()
6381
+ },
6382
+ year: {
6383
+ name: "Current Year",
6384
+ value: "{{system.year}}",
6385
+ sample: (/* @__PURE__ */ new Date()).getFullYear().toString()
6386
+ },
6387
+ unsubscribe: {
6388
+ name: "Unsubscribe Link",
6389
+ value: "{{system.unsubscribe}}",
6390
+ sample: "https://example.com/unsubscribe"
6391
+ }
6361
6392
  }
6362
6393
  }
6363
6394
  },
6364
- system: {
6365
- name: "System",
6366
- mergeTags: {
6367
- date: {
6368
- name: "Current Date",
6369
- value: "{{system.date}}",
6370
- sample: (/* @__PURE__ */ new Date()).toLocaleDateString()
6371
- },
6372
- year: {
6373
- name: "Current Year",
6374
- value: "{{system.year}}",
6375
- sample: (/* @__PURE__ */ new Date()).getFullYear().toString()
6376
- },
6377
- unsubscribe: {
6378
- name: "Unsubscribe Link",
6379
- value: "{{system.unsubscribe}}",
6380
- sample: "https://example.com/unsubscribe"
6381
- }
6395
+ // Special links
6396
+ specialLinks: {
6397
+ unsubscribe: {
6398
+ enabled: true,
6399
+ text: "Unsubscribe",
6400
+ href: "{{system.unsubscribe}}"
6401
+ },
6402
+ webview: {
6403
+ enabled: true,
6404
+ text: "View in browser",
6405
+ href: "{{system.webview}}"
6382
6406
  }
6383
- }
6384
- },
6385
- // Special links
6386
- specialLinks: {
6387
- unsubscribe: {
6388
- enabled: true,
6389
- text: "Unsubscribe",
6390
- href: "{{system.unsubscribe}}"
6391
6407
  },
6392
- webview: {
6408
+ // Custom CSS
6409
+ customCSS: [
6410
+ ".blockbuilder-content-email { font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif; }"
6411
+ ],
6412
+ // Validation
6413
+ validator: {
6393
6414
  enabled: true,
6394
- text: "View in browser",
6395
- href: "{{system.webview}}"
6396
- }
6397
- },
6398
- // Custom CSS
6399
- customCSS: [
6400
- ".blockbuilder-content-email { font-family: Inter, -apple-system, BlinkMacSystemFont, sans-serif; }"
6401
- ],
6402
- // Validation
6403
- validator: {
6404
- enabled: true,
6405
- rules: {
6406
- maxImageSize: 1024 * 1024
6407
- // 1MB
6415
+ rules: {
6416
+ maxImageSize: 1024 * 1024
6417
+ // 1MB
6418
+ }
6408
6419
  }
6409
6420
  }
6410
6421
  }
6411
- }
6412
- )
6413
- }
6414
- ) }) }),
6422
+ )
6423
+ }
6424
+ )
6425
+ ] }) }),
6415
6426
  /* @__PURE__ */ jsx(StyledTabsContent, { value: "text", children: /* @__PURE__ */ jsx(TextTabContent, { children: /* @__PURE__ */ jsx(
6416
6427
  Textarea,
6417
6428
  {
@@ -25,7 +25,7 @@ const index = {
25
25
  id: `${pluginId}.plugin.name`,
26
26
  defaultMessage: "MagicMail"
27
27
  },
28
- Component: () => Promise.resolve().then(() => require("../_chunks/App-DgnyvH-r.js"))
28
+ Component: () => Promise.resolve().then(() => require("../_chunks/App-CClpsmQH.js"))
29
29
  });
30
30
  app.createSettingSection(
31
31
  {
@@ -24,7 +24,7 @@ const index = {
24
24
  id: `${pluginId}.plugin.name`,
25
25
  defaultMessage: "MagicMail"
26
26
  },
27
- Component: () => import("../_chunks/App-BROmljEd.mjs")
27
+ Component: () => import("../_chunks/App-DQpXIAmV.mjs")
28
28
  });
29
29
  app.createSettingSection(
30
30
  {
@@ -4776,7 +4776,7 @@ function requireOauth() {
4776
4776
  });
4777
4777
  return oauth;
4778
4778
  }
4779
- const version = "1.0.2";
4779
+ const version = "1.0.4";
4780
4780
  const require$$2 = {
4781
4781
  version
4782
4782
  };
@@ -4768,7 +4768,7 @@ function requireOauth() {
4768
4768
  });
4769
4769
  return oauth;
4770
4770
  }
4771
- const version = "1.0.2";
4771
+ const version = "1.0.4";
4772
4772
  const require$$2 = {
4773
4773
  version
4774
4774
  };
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.3",
2
+ "version": "1.0.5",
3
3
  "keywords": [
4
4
  "strapi",
5
5
  "strapi-plugin",