@markopolo_ai_inc/markopolo-email-editor 1.0.3

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 (91) hide show
  1. package/README.md +63 -0
  2. package/build/asset-manifest.json +12 -0
  3. package/build/favicon.ico +0 -0
  4. package/build/index.html +1 -0
  5. package/build/logo192.png +0 -0
  6. package/build/logo512.png +0 -0
  7. package/build/manifest.json +25 -0
  8. package/build/robots.txt +3 -0
  9. package/build/static/css/main.588cb535.css +9 -0
  10. package/build/static/js/206.a4343501.chunk.js +1 -0
  11. package/build/static/js/main.053d366a.js +2 -0
  12. package/build/static/js/main.053d366a.js.LICENSE.txt +56 -0
  13. package/package.json +64 -0
  14. package/public/favicon.ico +0 -0
  15. package/public/index.html +50 -0
  16. package/public/logo192.png +0 -0
  17. package/public/logo512.png +0 -0
  18. package/public/manifest.json +25 -0
  19. package/public/robots.txt +3 -0
  20. package/src/App.js +15 -0
  21. package/src/components/EmailEditor/assets/App.css +339 -0
  22. package/src/components/EmailEditor/assets/Columns.css +309 -0
  23. package/src/components/EmailEditor/assets/Header.css +174 -0
  24. package/src/components/EmailEditor/assets/ImageBlock.css +12 -0
  25. package/src/components/EmailEditor/assets/Preview.css +30 -0
  26. package/src/components/EmailEditor/assets/RichText.css +199 -0
  27. package/src/components/EmailEditor/assets/RightSettings.css +520 -0
  28. package/src/components/EmailEditor/assets/Sidebar.css +195 -0
  29. package/src/components/EmailEditor/components/BlockItems/ButtonBlock.js +25 -0
  30. package/src/components/EmailEditor/components/BlockItems/DividerBlock.js +19 -0
  31. package/src/components/EmailEditor/components/BlockItems/HeadingBlock.js +16 -0
  32. package/src/components/EmailEditor/components/BlockItems/ImageBlock.js +28 -0
  33. package/src/components/EmailEditor/components/BlockItems/MenuBlock.js +52 -0
  34. package/src/components/EmailEditor/components/BlockItems/SocialLinkBlocks.js +26 -0
  35. package/src/components/EmailEditor/components/BlockItems/SpacerBlock.js +23 -0
  36. package/src/components/EmailEditor/components/BlockItems/TextBlock.js +16 -0
  37. package/src/components/EmailEditor/components/BlockItems/index.js +25 -0
  38. package/src/components/EmailEditor/components/ColorPicker/index.js +26 -0
  39. package/src/components/EmailEditor/components/Column/index.js +253 -0
  40. package/src/components/EmailEditor/components/Header/index.js +243 -0
  41. package/src/components/EmailEditor/components/LeftSideBar/index.js +253 -0
  42. package/src/components/EmailEditor/components/Main/index.js +281 -0
  43. package/src/components/EmailEditor/components/Preview/index.js +97 -0
  44. package/src/components/EmailEditor/components/RichText/Bold.js +37 -0
  45. package/src/components/EmailEditor/components/RichText/FontColor.js +39 -0
  46. package/src/components/EmailEditor/components/RichText/InsertOrderedList.js +36 -0
  47. package/src/components/EmailEditor/components/RichText/InsertUnorderedList.js +36 -0
  48. package/src/components/EmailEditor/components/RichText/Italic.js +36 -0
  49. package/src/components/EmailEditor/components/RichText/Link.js +99 -0
  50. package/src/components/EmailEditor/components/RichText/RichTextLayout.js +53 -0
  51. package/src/components/EmailEditor/components/RichText/Strikethrough.js +36 -0
  52. package/src/components/EmailEditor/components/RichText/TextAlign.js +58 -0
  53. package/src/components/EmailEditor/components/RichText/Underline.js +36 -0
  54. package/src/components/EmailEditor/components/RichText/index.js +210 -0
  55. package/src/components/EmailEditor/components/RightSetting/index.js +126 -0
  56. package/src/components/EmailEditor/components/StyleSettings/ButtonStyleSettings.js +141 -0
  57. package/src/components/EmailEditor/components/StyleSettings/ColumnStyleSettings.js +241 -0
  58. package/src/components/EmailEditor/components/StyleSettings/DividerStyleSettings.js +111 -0
  59. package/src/components/EmailEditor/components/StyleSettings/HeadingStyleSettings.js +162 -0
  60. package/src/components/EmailEditor/components/StyleSettings/ImageStyleSettings.js +217 -0
  61. package/src/components/EmailEditor/components/StyleSettings/MenuStyleSettings.js +177 -0
  62. package/src/components/EmailEditor/components/StyleSettings/PaddingSettings.js +30 -0
  63. package/src/components/EmailEditor/components/StyleSettings/SocialLinkSettings.js +250 -0
  64. package/src/components/EmailEditor/components/StyleSettings/SpacerStyleSettings.js +38 -0
  65. package/src/components/EmailEditor/components/StyleSettings/TextStyleSettings.js +108 -0
  66. package/src/components/EmailEditor/components/StyleSettings/index.js +32 -0
  67. package/src/components/EmailEditor/configs/getBlockConfigsList.js +263 -0
  68. package/src/components/EmailEditor/configs/getColumnConfigFunc.js +59 -0
  69. package/src/components/EmailEditor/configs/getColumnsSettings.js +246 -0
  70. package/src/components/EmailEditor/configs/useDataSource.js +19 -0
  71. package/src/components/EmailEditor/index.js +93 -0
  72. package/src/components/EmailEditor/reducers/index.js +173 -0
  73. package/src/components/EmailEditor/translation/en.js +166 -0
  74. package/src/components/EmailEditor/translation/index.js +39 -0
  75. package/src/components/EmailEditor/translation/zh.js +166 -0
  76. package/src/components/EmailEditor/utils/classNames.js +5 -0
  77. package/src/components/EmailEditor/utils/dataToHTML.js +323 -0
  78. package/src/components/EmailEditor/utils/exportValidation.js +296 -0
  79. package/src/components/EmailEditor/utils/helpers.js +48 -0
  80. package/src/components/EmailEditor/utils/pexels.js +20 -0
  81. package/src/components/EmailEditor/utils/useSection.js +24 -0
  82. package/src/components/EmailEditor/utils/useStyleLayout.js +82 -0
  83. package/src/index.css +99 -0
  84. package/src/index.js +15 -0
  85. package/src/logo.svg +1 -0
  86. package/src/pages/AppPage/index.js +10 -0
  87. package/src/pages/Dashboard/Header.js +192 -0
  88. package/src/pages/Dashboard/defaultBlockList.json +1758 -0
  89. package/src/pages/Dashboard/index.js +48 -0
  90. package/src/reportWebVitals.js +13 -0
  91. package/src/setupTests.js +5 -0
@@ -0,0 +1,192 @@
1
+ import { useState } from "react";
2
+ import { Modal, Button } from "antd";
3
+ import en from "../../components/EmailEditor/translation/en";
4
+ import zh from "../../components/EmailEditor/translation/zh";
5
+ import { validateExportPayload } from "../../components/EmailEditor/utils/exportValidation";
6
+
7
+ const Header = (props) => {
8
+ const { emailEditorEl, setLanguage, language = "en" } = props;
9
+ const langLib = language === "zh" ? zh : en;
10
+ const t = (key) => langLib[key] || key;
11
+
12
+ const [validationModalOpen, setValidationModalOpen] = useState(false);
13
+ const [validationIssues, setValidationIssues] = useState([]);
14
+ const [pendingExportType, setPendingExportType] = useState(null); // "json" | "html"
15
+
16
+ const getPayload = () => {
17
+ const blockList = emailEditorEl.current?.blockList ?? [];
18
+ const bodySettings = emailEditorEl.current?.bodySettings ?? null;
19
+ return { blockList, bodySettings };
20
+ };
21
+
22
+ const doExportHTML = () => {
23
+ const html = emailEditorEl.current?.exportHtml?.();
24
+ if (html == null) return;
25
+ const blob = new Blob([html], { type: "text/html" });
26
+ const a = document.createElement("a");
27
+ a.download = "email.html";
28
+ a.href = URL.createObjectURL(blob);
29
+ a.click();
30
+ };
31
+
32
+ const doExportJSON = () => {
33
+ const { blockList, bodySettings } = getPayload();
34
+ const payload = bodySettings ? { blockList, bodySettings } : blockList;
35
+ const json = JSON.stringify(payload, null, 2);
36
+ const blob = new Blob([json], { type: "application/json" });
37
+ const a = document.createElement("a");
38
+ a.download = "email-template.json";
39
+ a.href = URL.createObjectURL(blob);
40
+ a.click();
41
+ };
42
+
43
+ const runExportOrShowValidation = (exportType) => {
44
+ const payload = getPayload();
45
+ const issues = validateExportPayload(payload);
46
+ if (issues.length === 0) {
47
+ if (exportType === "html") doExportHTML();
48
+ else doExportJSON();
49
+ return;
50
+ }
51
+ setValidationIssues(issues);
52
+ setPendingExportType(exportType);
53
+ setValidationModalOpen(true);
54
+ };
55
+
56
+ const closeValidationModal = () => {
57
+ setValidationModalOpen(false);
58
+ setValidationIssues([]);
59
+ setPendingExportType(null);
60
+ };
61
+
62
+ const handleExportAnyway = () => {
63
+ if (pendingExportType === "html") doExportHTML();
64
+ else if (pendingExportType === "json") doExportJSON();
65
+ closeValidationModal();
66
+ };
67
+
68
+ const errors = validationIssues.filter((i) => i.severity === "error");
69
+ const warnings = validationIssues.filter((i) => i.severity === "warning");
70
+ const infos = validationIssues.filter((i) => i.severity === "info");
71
+
72
+ // Reserved for language switcher UI
73
+ // eslint-disable-next-line no-unused-vars
74
+ const changeLanguage = (language) => () => {
75
+ setLanguage(language);
76
+ };
77
+
78
+ return (
79
+ <div className="dashboard-header">
80
+ <div className="dashboard-header-title">
81
+ Markopolo Email Template Editor
82
+ </div>
83
+ <div className="dashboard-header-feature">
84
+ <button
85
+ className="dashboard-header-subtitle"
86
+ onClick={() => runExportOrShowValidation("json")}
87
+ >
88
+ {t("export_json")}
89
+ </button>
90
+ <button
91
+ className="dashboard-header-subtitle"
92
+ onClick={() => runExportOrShowValidation("html")}
93
+ >
94
+ {t("export_html")}
95
+ </button>
96
+ </div>
97
+
98
+ <Modal
99
+ className="ee-modal-dark"
100
+ title={t("export_validation_title")}
101
+ open={validationModalOpen}
102
+ onCancel={closeValidationModal}
103
+ footer={[
104
+ <Button key="cancel" onClick={closeValidationModal}>
105
+ {t("cancel")}
106
+ </Button>,
107
+ <Button key="export" type="primary" onClick={handleExportAnyway}>
108
+ {t("export_anyway")}
109
+ </Button>,
110
+ ]}
111
+ width={520}
112
+ >
113
+ <p style={{ marginBottom: 12 }}>
114
+ {t("export_validation_issues_found")}
115
+ </p>
116
+ <div style={{ maxHeight: 360, overflowY: "auto" }}>
117
+ {errors.length > 0 && (
118
+ <div style={{ marginBottom: 12 }}>
119
+ <div
120
+ className="export-validation-errors-heading"
121
+ style={{ fontWeight: 600, marginBottom: 6 }}
122
+ >
123
+ {t("export_validation_errors")} ({errors.length})
124
+ </div>
125
+ <ul style={{ margin: 0, paddingLeft: 20 }}>
126
+ {errors.map((issue, idx) => (
127
+ <li key={`e-${idx}`} style={{ marginBottom: 4 }}>
128
+ {t("validation_" + issue.code) || issue.message}
129
+ {issue.location && (
130
+ <span className="export-validation-location" style={{ fontSize: 12 }}>
131
+ {" "}
132
+ — {issue.location}
133
+ </span>
134
+ )}
135
+ </li>
136
+ ))}
137
+ </ul>
138
+ </div>
139
+ )}
140
+ {warnings.length > 0 && (
141
+ <div style={{ marginBottom: 12 }}>
142
+ <div
143
+ className="export-validation-warnings-heading"
144
+ style={{ fontWeight: 600, marginBottom: 6 }}
145
+ >
146
+ {t("export_validation_warnings")} ({warnings.length})
147
+ </div>
148
+ <ul style={{ margin: 0, paddingLeft: 20 }}>
149
+ {warnings.map((issue, idx) => (
150
+ <li key={`w-${idx}`} style={{ marginBottom: 4 }}>
151
+ {t("validation_" + issue.code) || issue.message}
152
+ {issue.location && (
153
+ <span className="export-validation-location" style={{ fontSize: 12 }}>
154
+ {" "}
155
+ — {issue.location}
156
+ </span>
157
+ )}
158
+ </li>
159
+ ))}
160
+ </ul>
161
+ </div>
162
+ )}
163
+ {infos.length > 0 && (
164
+ <div>
165
+ <div
166
+ className="export-validation-info-heading"
167
+ style={{ fontWeight: 600, marginBottom: 6 }}
168
+ >
169
+ {t("export_validation_info")} ({infos.length})
170
+ </div>
171
+ <ul style={{ margin: 0, paddingLeft: 20 }}>
172
+ {infos.map((issue, idx) => (
173
+ <li key={`i-${idx}`} style={{ marginBottom: 4 }}>
174
+ {t("validation_" + issue.code) || issue.message}
175
+ {issue.location && (
176
+ <span className="export-validation-location" style={{ fontSize: 12 }}>
177
+ {" "}
178
+ — {issue.location}
179
+ </span>
180
+ )}
181
+ </li>
182
+ ))}
183
+ </ul>
184
+ </div>
185
+ )}
186
+ </div>
187
+ </Modal>
188
+ </div>
189
+ );
190
+ };
191
+
192
+ export default Header;