@openlettermarketing/olc-react-sdk 2.1.4 → 2.1.5-beta.2

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 (230) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc.cjs +18 -0
  3. package/.eslintrc.yml +47 -0
  4. package/.github/workflows/publish-beta.yml +154 -0
  5. package/.github/workflows/publish-production.yml +143 -0
  6. package/.prettierignore +3 -0
  7. package/.prettierrc.yml +5 -0
  8. package/CHANGELOG.md +4 -0
  9. package/babel.config.json +10 -0
  10. package/build/index.js +82 -82
  11. package/build/index.js.map +1 -1
  12. package/build/types/version.d.ts +1 -1
  13. package/examples/.eslintrc.yml +4 -0
  14. package/index.html +18 -0
  15. package/package.json +1 -1
  16. package/public/vite.svg +1 -0
  17. package/src/App.tsx +209 -0
  18. package/src/assets/Fonts/Lexi-Regular.ttf +0 -0
  19. package/src/assets/images/create-template/prebuilt.svg +13 -0
  20. package/src/assets/images/create-template/scratch.svg +4 -0
  21. package/src/assets/images/input/cancel.tsx +20 -0
  22. package/src/assets/images/input/search.tsx +20 -0
  23. package/src/assets/images/input/select-cancel.tsx +17 -0
  24. package/src/assets/images/modal-icons/add.tsx +36 -0
  25. package/src/assets/images/modal-icons/cancel-file.tsx +12 -0
  26. package/src/assets/images/modal-icons/cancel-input.tsx +13 -0
  27. package/src/assets/images/modal-icons/cancel.tsx +35 -0
  28. package/src/assets/images/modal-icons/close-new.svg +3 -0
  29. package/src/assets/images/modal-icons/confirm-close-icon.tsx +14 -0
  30. package/src/assets/images/modal-icons/confirm-new.tsx +22 -0
  31. package/src/assets/images/modal-icons/confirm.svg +12 -0
  32. package/src/assets/images/modal-icons/cross.tsx +23 -0
  33. package/src/assets/images/modal-icons/del.tsx +19 -0
  34. package/src/assets/images/modal-icons/design-icon.tsx +22 -0
  35. package/src/assets/images/modal-icons/doc.tsx +43 -0
  36. package/src/assets/images/modal-icons/docx.tsx +43 -0
  37. package/src/assets/images/modal-icons/envelope-icon.tsx +26 -0
  38. package/src/assets/images/modal-icons/info.tsx +19 -0
  39. package/src/assets/images/modal-icons/jpeg.tsx +43 -0
  40. package/src/assets/images/modal-icons/jpg.tsx +43 -0
  41. package/src/assets/images/modal-icons/modal-cros.svg +4 -0
  42. package/src/assets/images/modal-icons/modal-cross.tsx +37 -0
  43. package/src/assets/images/modal-icons/new-cancel.tsx +11 -0
  44. package/src/assets/images/modal-icons/order-download.tsx +42 -0
  45. package/src/assets/images/modal-icons/pdf.tsx +51 -0
  46. package/src/assets/images/modal-icons/png.tsx +43 -0
  47. package/src/assets/images/modal-icons/save.tsx +23 -0
  48. package/src/assets/images/modal-icons/template-copy.tsx +25 -0
  49. package/src/assets/images/modal-icons/tool-cancel.tsx +25 -0
  50. package/src/assets/images/products/bi-new.svg +23 -0
  51. package/src/assets/images/products/left-arrow.svg +17 -0
  52. package/src/assets/images/products/personal-new.tsx +31 -0
  53. package/src/assets/images/products/postcard-new.tsx +27 -0
  54. package/src/assets/images/products/professional-new.tsx +24 -0
  55. package/src/assets/images/products/real-new.tsx +30 -0
  56. package/src/assets/images/products/right-arrow.svg +17 -0
  57. package/src/assets/images/products/snap-new.svg +31 -0
  58. package/src/assets/images/templates/actions.svg +3 -0
  59. package/src/assets/images/templates/address-block-icon.tsx +62 -0
  60. package/src/assets/images/templates/archive.svg +3 -0
  61. package/src/assets/images/templates/arrow-down.tsx +27 -0
  62. package/src/assets/images/templates/back-arrow.tsx +19 -0
  63. package/src/assets/images/templates/bi-fold-self-mailers.tsx +28 -0
  64. package/src/assets/images/templates/check.svg +3 -0
  65. package/src/assets/images/templates/code.svg +10 -0
  66. package/src/assets/images/templates/content-copy-icon.tsx +24 -0
  67. package/src/assets/images/templates/custom-add-on-icon.tsx +18 -0
  68. package/src/assets/images/templates/custom-qr-section-icon.tsx +9 -0
  69. package/src/assets/images/templates/custom-template.tsx +23 -0
  70. package/src/assets/images/templates/designer.tsx +43 -0
  71. package/src/assets/images/templates/dot.tsx +22 -0
  72. package/src/assets/images/templates/download-v2.svg +4 -0
  73. package/src/assets/images/templates/download.svg +4 -0
  74. package/src/assets/images/templates/dummy-template.tsx +76 -0
  75. package/src/assets/images/templates/dynamic-field.tsx +119 -0
  76. package/src/assets/images/templates/edit-pencil-icon.tsx +21 -0
  77. package/src/assets/images/templates/edit.svg +3 -0
  78. package/src/assets/images/templates/epo-icon.tsx +16 -0
  79. package/src/assets/images/templates/field.tsx +29 -0
  80. package/src/assets/images/templates/gsv-icon.tsx +31 -0
  81. package/src/assets/images/templates/info-icon.tsx +37 -0
  82. package/src/assets/images/templates/left-arrow.svg +17 -0
  83. package/src/assets/images/templates/pencil.svg +3 -0
  84. package/src/assets/images/templates/personal-letter.tsx +53 -0
  85. package/src/assets/images/templates/postcard.tsx +32 -0
  86. package/src/assets/images/templates/professional-letter.tsx +53 -0
  87. package/src/assets/images/templates/qr-code.tsx +13 -0
  88. package/src/assets/images/templates/real-penned-letters.tsx +57 -0
  89. package/src/assets/images/templates/right-arrow.svg +17 -0
  90. package/src/assets/images/templates/size-image-lg.tsx +20 -0
  91. package/src/assets/images/templates/size-image-mid.tsx +20 -0
  92. package/src/assets/images/templates/size-image-xl.tsx +20 -0
  93. package/src/assets/images/templates/size-image.tsx +20 -0
  94. package/src/assets/images/templates/snap-pack.tsx +67 -0
  95. package/src/assets/images/templates/template-default-design.tsx +21 -0
  96. package/src/assets/images/templates/trash-upload.svg +3 -0
  97. package/src/assets/images/templates/trash.svg +3 -0
  98. package/src/assets/images/templates/tri-fold-self-mailers.tsx +93 -0
  99. package/src/assets/images/templates/upload-image.svg +10 -0
  100. package/src/assets/images/templates/x.svg +3 -0
  101. package/src/assets/images/thumbnails/one.svg +9 -0
  102. package/src/assets/images/tooltip/tool-arrow.tsx +25 -0
  103. package/src/components/CreateTemplate/V2/index.tsx +525 -0
  104. package/src/components/CreateTemplate/V2/styles.scss +372 -0
  105. package/src/components/CreateTemplate/index.tsx +508 -0
  106. package/src/components/CreateTemplate/styles.scss +404 -0
  107. package/src/components/GenericUIBlocks/Button/index.tsx +54 -0
  108. package/src/components/GenericUIBlocks/Button/styles.scss +43 -0
  109. package/src/components/GenericUIBlocks/CircularProgress/index.tsx +18 -0
  110. package/src/components/GenericUIBlocks/CircularProgress/styles.scss +93 -0
  111. package/src/components/GenericUIBlocks/CustomTooltip/index.tsx +88 -0
  112. package/src/components/GenericUIBlocks/CustomTooltip/styles.scss +19 -0
  113. package/src/components/GenericUIBlocks/Dialog/V2/index.tsx +227 -0
  114. package/src/components/GenericUIBlocks/Dialog/V2/styles.scss +289 -0
  115. package/src/components/GenericUIBlocks/Dialog/index.tsx +185 -0
  116. package/src/components/GenericUIBlocks/Dialog/styles.scss +227 -0
  117. package/src/components/GenericUIBlocks/Divider/index.tsx +12 -0
  118. package/src/components/GenericUIBlocks/Divider/styles.scss +7 -0
  119. package/src/components/GenericUIBlocks/GeneralSelect/index.tsx +114 -0
  120. package/src/components/GenericUIBlocks/GeneralSelect/styles.scss +406 -0
  121. package/src/components/GenericUIBlocks/GeneralTooltip/index.tsx +25 -0
  122. package/src/components/GenericUIBlocks/GeneralTooltip/styles.scss +20 -0
  123. package/src/components/GenericUIBlocks/GenericSnackbar/Toast/index.tsx +91 -0
  124. package/src/components/GenericUIBlocks/GenericSnackbar/Toast/styles.scss +92 -0
  125. package/src/components/GenericUIBlocks/Grid/index.tsx +82 -0
  126. package/src/components/GenericUIBlocks/Input/index.tsx +269 -0
  127. package/src/components/GenericUIBlocks/Input/styles.scss +332 -0
  128. package/src/components/GenericUIBlocks/Tabs/index.tsx +71 -0
  129. package/src/components/GenericUIBlocks/Tabs/styles.scss +42 -0
  130. package/src/components/GenericUIBlocks/Typography/index.tsx +18 -0
  131. package/src/components/GenericUIBlocks/Typography/styles.scss +27 -0
  132. package/src/components/SidePanel/CustomAddOns/index.tsx +342 -0
  133. package/src/components/SidePanel/CustomAddOns/styles.scss +86 -0
  134. package/src/components/SidePanel/CustomBlockColors/index.tsx +211 -0
  135. package/src/components/SidePanel/CustomBlockColors/styles.scss +80 -0
  136. package/src/components/SidePanel/CustomFields/customFieldSection.tsx +547 -0
  137. package/src/components/SidePanel/CustomFields/styles.scss +64 -0
  138. package/src/components/SidePanel/CustomQRCode/V2/QRCodeModal/index.tsx +172 -0
  139. package/src/components/SidePanel/CustomQRCode/V2/QRCodeModal/styles.scss +46 -0
  140. package/src/components/SidePanel/CustomQRCode/index.tsx +1070 -0
  141. package/src/components/SidePanel/CustomQRCode/styles.scss +149 -0
  142. package/src/components/SidePanel/CustomUploads/V2/index.tsx +542 -0
  143. package/src/components/SidePanel/CustomUploads/V2/styles.scss +267 -0
  144. package/src/components/SidePanel/CustomUploads/index.tsx +301 -0
  145. package/src/components/SidePanel/Templates/ModalGallery/HireDesigner/index.tsx +424 -0
  146. package/src/components/SidePanel/Templates/ModalGallery/HireDesigner/styles.scss +180 -0
  147. package/src/components/SidePanel/Templates/ModalGallery/V2/index.tsx +235 -0
  148. package/src/components/SidePanel/Templates/ModalGallery/V2/styles.scss +244 -0
  149. package/src/components/SidePanel/Templates/ModalGallery/index.tsx +231 -0
  150. package/src/components/SidePanel/Templates/SideBarGallery/index.tsx +233 -0
  151. package/src/components/SidePanel/Templates/SideBarGallery/styles.scss +152 -0
  152. package/src/components/SidePanel/Templates/TemplatesCard/V2/index.tsx +149 -0
  153. package/src/components/SidePanel/Templates/TemplatesCard/V2/styles.scss +156 -0
  154. package/src/components/SidePanel/Templates/TemplatesCard/index.tsx +160 -0
  155. package/src/components/SidePanel/Templates/TemplatesCard/styles.scss +98 -0
  156. package/src/components/SidePanel/Templates/customTemplateSection.tsx +793 -0
  157. package/src/components/SidePanel/Templates/styles.scss +244 -0
  158. package/src/components/SidePanel/index.tsx +160 -0
  159. package/src/components/TemplateBuilder/index.tsx +585 -0
  160. package/src/components/TemplateBuilder/styles.scss +100 -0
  161. package/src/components/TemplateTypes/index.tsx +96 -0
  162. package/src/components/TemplateTypes/styles.scss +91 -0
  163. package/src/components/TopNavigation/ConfirmNavigateDialog/index.tsx +81 -0
  164. package/src/components/TopNavigation/ConfirmNavigateDialog/styles.scss +123 -0
  165. package/src/components/TopNavigation/DuplicateTemplateModal.tsx +103 -0
  166. package/src/components/TopNavigation/EditTemplateNameModel/index.tsx +71 -0
  167. package/src/components/TopNavigation/EditTemplateNameModel/styles.scss +88 -0
  168. package/src/components/TopNavigation/SaveTemplateModel/index.tsx +201 -0
  169. package/src/components/TopNavigation/SaveTemplateModel/styles.scss +128 -0
  170. package/src/components/TopNavigation/index.tsx +938 -0
  171. package/src/components/TopNavigation/styles.scss +303 -0
  172. package/src/importMeta.d.ts +31 -0
  173. package/src/index.scss +131 -0
  174. package/src/index.tsx +238 -0
  175. package/src/libs/test.ts +7 -0
  176. package/src/redux/actions/action-types.ts +52 -0
  177. package/src/redux/actions/customQRCodeActions.ts +54 -0
  178. package/src/redux/actions/snackbarActions.ts +16 -0
  179. package/src/redux/actions/templateActions.ts +236 -0
  180. package/src/redux/reducers/customFieldReducer.ts +99 -0
  181. package/src/redux/reducers/customQRCodeReducer.ts +58 -0
  182. package/src/redux/reducers/index.ts +15 -0
  183. package/src/redux/reducers/snackbarReducer.ts +40 -0
  184. package/src/redux/reducers/templateReducer.ts +485 -0
  185. package/src/redux/store.ts +18 -0
  186. package/src/styles/colors.scss +61 -0
  187. package/src/test/mocks.js +89 -0
  188. package/src/test/setupJest.js +1 -0
  189. package/src/utils/api.ts +36 -0
  190. package/src/utils/constants.ts +182 -0
  191. package/src/utils/customStyles.ts +45 -0
  192. package/src/utils/fetchWrapper.ts +73 -0
  193. package/src/utils/fonts.json +1597 -0
  194. package/src/utils/helper.ts +205 -0
  195. package/src/utils/local-storage.ts +15 -0
  196. package/src/utils/message.ts +162 -0
  197. package/src/utils/products.ts +186 -0
  198. package/src/utils/template-builder.ts +328 -0
  199. package/src/utils/templateIdentifierArea/biFold.ts +107 -0
  200. package/src/utils/templateIdentifierArea/index.ts +35 -0
  201. package/src/utils/templateIdentifierArea/personal.ts +107 -0
  202. package/src/utils/templateIdentifierArea/postCards.ts +163 -0
  203. package/src/utils/templateIdentifierArea/professional.ts +125 -0
  204. package/src/utils/templateIdentifierArea/snapPack.ts +107 -0
  205. package/src/utils/templateIdentifierArea/triFold.ts +107 -0
  206. package/src/utils/templateRestrictedArea/biFold.ts +329 -0
  207. package/src/utils/templateRestrictedArea/nonWindowProfessional.ts +90 -0
  208. package/src/utils/templateRestrictedArea/personal.ts +90 -0
  209. package/src/utils/templateRestrictedArea/postCard.ts +334 -0
  210. package/src/utils/templateRestrictedArea/postCardJumbo.tsx +408 -0
  211. package/src/utils/templateRestrictedArea/professional.ts +318 -0
  212. package/src/utils/templateRestrictedArea/realPenned.ts +233 -0
  213. package/src/utils/templateRestrictedArea/snapPack.ts +1009 -0
  214. package/src/utils/templateRestrictedArea/triFold.ts +330 -0
  215. package/src/utils/templateSafetyBorders/biFold.ts +91 -0
  216. package/src/utils/templateSafetyBorders/index.ts +43 -0
  217. package/src/utils/templateSafetyBorders/personal.ts +41 -0
  218. package/src/utils/templateSafetyBorders/postCards.ts +259 -0
  219. package/src/utils/templateSafetyBorders/professional.ts +78 -0
  220. package/src/utils/templateSafetyBorders/snapPack.ts +165 -0
  221. package/src/utils/templateSafetyBorders/triFold.ts +114 -0
  222. package/src/utils/templateSafetyBorders/types.d.ts +68 -0
  223. package/src/utils/types.ts +12 -0
  224. package/src/v2Theme.scss +142 -0
  225. package/tsconfig.json +29 -0
  226. package/tsconfig.node.json +12 -0
  227. package/update-version.js +23 -0
  228. package/version.js +1 -0
  229. package/vite.config.ts +8 -0
  230. package/webpack.config.js +80 -0
@@ -0,0 +1,938 @@
1
+ import React, { useEffect, useState } from 'react';
2
+
3
+ // Hooks
4
+ import { useDispatch, useSelector } from 'react-redux';
5
+ import { useNavigate, useParams } from 'react-router-dom';
6
+ import { AppDispatch, RootState } from '../../redux/store';
7
+
8
+ // Actions
9
+ import {
10
+ clearTemplateFields,
11
+ loadFormDataToStore,
12
+ downloadProof,
13
+ envelopeProof,
14
+ setPageCount,
15
+ } from '../../redux/actions/templateActions';
16
+ import { failure, success } from '../../redux/actions/snackbarActions';
17
+ import { searchAndAdvanceChange } from '../../redux/actions/templateActions';
18
+
19
+ // Components
20
+ import SaveTemplateModel from './SaveTemplateModel';
21
+ import ConfirmNavigateDialog from './ConfirmNavigateDialog';
22
+ import EditTemplateNameModel from './EditTemplateNameModel';
23
+
24
+ // Utils
25
+ import {
26
+ changeColorOfBoxesForSnapPack,
27
+ downloadPDF,
28
+ extractFontFamilies,
29
+ isValidQR,
30
+ multiPageTemplates,
31
+ removeBracketsFromRPL,
32
+ validateEmoji,
33
+ validateGSV,
34
+ } from '../../utils/template-builder';
35
+ import { addSafetyBordersToNonWindowProfessioanl } from '../../utils/templateSafetyBorders/professional';
36
+ import { addIdentifierAreaToProfessionalNonWindow } from '../../utils/templateIdentifierArea/professional';
37
+ import { getItem, setItem } from '../../utils/local-storage';
38
+ import { MESSAGES } from '../../utils/message';
39
+ // @ts-ignore
40
+ import fonts from '../../utils/fonts.json';
41
+
42
+ // UI Components
43
+ import Typography from '../GenericUIBlocks/Typography';
44
+ import Button from '../GenericUIBlocks/Button';
45
+ import CircularProgress from '../GenericUIBlocks/CircularProgress';
46
+ import { GridContainer, GridItem } from '../GenericUIBlocks/Grid';
47
+ import DuplicateTemplateModal from './DuplicateTemplateModal';
48
+ import GeneralTooltip from '../GenericUIBlocks/GeneralTooltip';
49
+
50
+ // Icons
51
+ // @ts-ignore
52
+ import EditIcon from '../../assets/images/templates/edit-pencil-icon.tsx';
53
+ // @ts-ignore
54
+ import DownloadIcon from '../../assets/images/modal-icons/order-download.tsx';
55
+ // @ts-ignore
56
+ import EnvelopeIcon from '../../assets/images/modal-icons/envelope-icon.tsx';
57
+ // @ts-ignore
58
+ import CloneIcon from '../../assets/images/modal-icons/template-copy.tsx';
59
+ // @ts-ignore
60
+ import AddIcon from '../../assets/images/modal-icons/add.tsx';
61
+ // @ts-ignore
62
+ import DeleteIcon from '../../assets/images/modal-icons/del.tsx';
63
+ // @ts-ignore
64
+ import DownloadIconV2 from '../../assets/images/templates/download-v2.svg';
65
+ // @ts-ignore
66
+ import CheckIconV2 from '../../assets/images/templates/check.svg';
67
+ // @ts-ignore
68
+ import EditIconV2 from '../../assets/images/templates/x.svg';
69
+ // @ts-ignore
70
+ import PencilIcon from '../../assets/images/templates/pencil.svg';
71
+
72
+ // Styles
73
+ import './styles.scss';
74
+
75
+ /**
76
+ * Represents the top navigation bar of a template builder application.
77
+ * Handles saving and navigation logic, as well as displaying a confirmation dialog for unsaved changes.
78
+ *
79
+ * @param {Object} props - The component props.
80
+ * @param {Object} props.store - The store object used for saving the template.
81
+ * @param {boolean} props.isStoreUpdated - Indicates whether the store has been updated.
82
+ * @returns {JSX.Element} The top navigation bar component.
83
+ */
84
+
85
+ const buttonStyles: React.CSSProperties = {
86
+ maxWidth: '120px',
87
+ minHeight: '40px',
88
+ backgroundColor: '#fff',
89
+ color: 'var(--text-color)',
90
+ border: '0.5px solid var(--border-color)',
91
+ fontSize: '15px',
92
+ fontWeight: '500',
93
+ };
94
+
95
+ const progressStyles: React.CSSProperties = {
96
+ width: '20px',
97
+ height: '20px',
98
+ border: '2px solid var(--primary-color)',
99
+ };
100
+
101
+ interface TopNavigationProps {
102
+ store: any;
103
+ createTemplateRoute?: string | null;
104
+ isStoreUpdated: boolean;
105
+ setIsDuplication: any;
106
+ olcTemplate?: Record<string, any>;
107
+ designerTemplateQuery?: Record<string, any> | null;
108
+ allowedAddOns?: any;
109
+ allowAdditionalPage?: boolean;
110
+ currentTheme?: string | null | undefined;
111
+ onDuplicateTemplate?: (payload: any) => Promise<any>;
112
+ onReturnAndNavigate?: () => void;
113
+ onSubmit?: (payload: any) => Promise<any>;
114
+ }
115
+
116
+ const TopNavigation: React.FC<TopNavigationProps> = ({
117
+ store,
118
+ createTemplateRoute,
119
+ isStoreUpdated,
120
+ setIsDuplication,
121
+ olcTemplate,
122
+ designerTemplateQuery,
123
+ allowedAddOns,
124
+ allowAdditionalPage,
125
+ currentTheme,
126
+ onDuplicateTemplate,
127
+ onReturnAndNavigate,
128
+ onSubmit,
129
+ }) => {
130
+ const [showNavigateDialog, setShowNavigateDialog] = useState<boolean>(false);
131
+ const [isShowModel, setIsShowModel] = useState<{
132
+ open: boolean;
133
+ model: string;
134
+ loading: boolean;
135
+ inputValue?: string;
136
+ }>({
137
+ open: false,
138
+ model: '',
139
+ loading: false,
140
+ inputValue: '',
141
+ });
142
+ const [downloadingProof, setDownloaingProof] = useState<boolean>(false);
143
+ const [downloadingEnvelope, setDownloaingEnvelope] = useState<boolean>(false);
144
+ const [templateTitle, setTemplateTitle] = useState('');
145
+
146
+ const { id } = useParams<{ id: string }>();
147
+
148
+ const dispatch: AppDispatch = useDispatch();
149
+ const navigate = useNavigate();
150
+
151
+ const title = useSelector((state: RootState) => state.templates.title) || '';
152
+
153
+
154
+ const product = useSelector(
155
+ (state: RootState) => state.templates.product
156
+ ) as Record<string, any>;
157
+ const pageCount = useSelector(
158
+ (state: RootState) => state.templates.pageCount
159
+ );
160
+
161
+ const dynamicFields = useSelector(
162
+ (state: RootState) => state.templates.dynamicFields
163
+ );
164
+ const defaultFields = useSelector(
165
+ (state: RootState) => state.templates.defaultDynamicFields
166
+ );
167
+
168
+ const defaultSenderFields = useSelector(
169
+ (state: RootState) => state.templates.defaultSenderFields
170
+ );
171
+
172
+ const customFields = useSelector(
173
+ (state: RootState) => state.customFields.customFields
174
+ );
175
+
176
+ const customFieldsV2 = useSelector(
177
+ (state: RootState) => state.customFields.customFieldsV2
178
+ ) as Record<string, any>;
179
+
180
+ const defaultPropertyFields = useSelector(
181
+ (state: RootState) => state.templates.defaultPropertyFields
182
+ );
183
+
184
+ const templateType = useSelector(
185
+ (state: RootState) => state.templates.templateType
186
+ );
187
+ const envelopeType = useSelector(
188
+ (state: RootState) => state.templates.envelopeType
189
+ );
190
+
191
+ const rosOfferPercentage = useSelector(
192
+ (state: RootState) => state.templates.offerPercentage
193
+ );
194
+
195
+ const defaultMiscFields = useSelector(
196
+ (state: RootState) => state.templates.defaultMiscFields
197
+ );
198
+
199
+ useEffect(() => {
200
+ setTemplateTitle(title);
201
+ }, [title]);
202
+
203
+ useEffect(() => {
204
+ if (!id) {
205
+ const formData = getItem('formData');
206
+ if (formData && !title) {
207
+ dispatch(loadFormDataToStore(formData));
208
+ } else {
209
+ handleSaveFormData();
210
+ }
211
+ }
212
+ }, [title]);
213
+
214
+ // Update page count when store pages change
215
+ useEffect(() => {
216
+ if (store && store.pages) {
217
+ dispatch(setPageCount(store.pages.length));
218
+ }
219
+ }, [store?.pages?.length]);
220
+
221
+ const handleSaveFormData = () => {
222
+ const data = { title, product, templateType, envelopeType };
223
+ setItem('formData', JSON.stringify(data));
224
+ };
225
+
226
+ const handleBackPress = () => {
227
+ if (isStoreUpdated) {
228
+ setShowNavigateDialog(!showNavigateDialog);
229
+ } else {
230
+ handleNavigation(createTemplateRoute || '/create-template');
231
+ }
232
+ };
233
+
234
+ const closeDuplicateModal = () => {
235
+ setIsShowModel((prev) => ({
236
+ ...prev,
237
+ open: false,
238
+ model: '',
239
+ inputValue: '',
240
+ }));
241
+ };
242
+
243
+ const handleNavigation = async (route = '/') => {
244
+ handleClearFilters();
245
+ if (
246
+ templateType === 'json' &&
247
+ product?.productType !== 'Real Penned Letter'
248
+ ) {
249
+ await store.history.clear();
250
+ }
251
+ onReturnAndNavigate ? onReturnAndNavigate() : navigate(route);
252
+ };
253
+
254
+ const handleClearFilters = () => dispatch(clearTemplateFields());
255
+
256
+ const isProfessionalLetterNonWindow = () => {
257
+ return (
258
+ product?.id === '4' &&
259
+ product?.productType === 'Professional Letters' &&
260
+ (product?.windowed === false || product.isWindowedEnvelope === false)
261
+ );
262
+ };
263
+
264
+ // Add a new page
265
+ const handleAddPage = () => {
266
+ if (store && store.pages.length < 2) {
267
+ store.addPage();
268
+ addSafetyBordersToNonWindowProfessioanl(store, 1);
269
+ addIdentifierAreaToProfessionalNonWindow(store, 1);
270
+ dispatch(setPageCount(store.pages.length));
271
+ }
272
+ };
273
+
274
+ // Delete the second page
275
+ const handleDeletePage = () => {
276
+ if (store && store.pages.length > 1) {
277
+ const pageToDelete = store.pages[1];
278
+ store.deletePages([pageToDelete.id]);
279
+ dispatch(setPageCount(store.pages.length));
280
+ }
281
+ };
282
+
283
+ // Handle the duplication of the template
284
+ const handleEditName = async () => {
285
+ let errorText = '';
286
+ if (!templateTitle) {
287
+ errorText = MESSAGES.TEMPLATE.NAME_REQUIRED;
288
+ } else if (templateTitle.length > 50) {
289
+ errorText = MESSAGES.TEMPLATE.NAME_LESS_50;
290
+ }
291
+ if (errorText) {
292
+ dispatch(failure(errorText));
293
+ return;
294
+ }
295
+ dispatch(searchAndAdvanceChange('title', templateTitle.trim()));
296
+ handleChangeModel()
297
+ };
298
+
299
+ const handleViewProofWithLamda = async () => {
300
+ try {
301
+ setDownloaingProof(true);
302
+ let flattenedFieldsV2 = [];
303
+ if (customFieldsV2.length > 0) {
304
+ flattenedFieldsV2 = customFieldsV2?.flatMap(
305
+ (section: { fields: any }) => section.fields
306
+ );
307
+ }
308
+ const fields = [
309
+ ...defaultFields,
310
+ ...customFields,
311
+ ...flattenedFieldsV2,
312
+ ...Object.values(dynamicFields),
313
+ ...defaultSenderFields,
314
+ ...defaultPropertyFields,
315
+ ...defaultMiscFields,
316
+ {
317
+ value: '{{ROS.PROPERTY_OFFER}}',
318
+ key: '{{ROS.PROPERTY_OFFER}}',
319
+ defaultValue: '$123,456.00',
320
+ },
321
+ ];
322
+ let json = store.toJSON();
323
+ const jsonSize = new Blob([JSON.stringify(json)]).size;
324
+ if (jsonSize > 5242880) {
325
+ dispatch(failure(MESSAGES.TEMPLATE.SIZE_LIMIT_EXCEED));
326
+ return;
327
+ }
328
+ if (product?.productType === 'Real Penned Letter' && +product.id === 16) {
329
+ const removedUnsupportedBrackets = removeBracketsFromRPL(json);
330
+ json = removedUnsupportedBrackets;
331
+ let clonedJson = JSON.stringify(json)
332
+ .replace(/\(\(/g, '{{')
333
+ .replace(/\)\)/g, '}}');
334
+ json = JSON.parse(clonedJson);
335
+ }
336
+ if (product.productType === 'Snap Pack Mailers') {
337
+ const updatedBoxes = changeColorOfBoxesForSnapPack(json);
338
+ json = updatedBoxes;
339
+ }
340
+ let jsonString = JSON.stringify(json);
341
+ fields.forEach(({ key, defaultValue, value }) => {
342
+ const regex = new RegExp(key, 'g');
343
+ jsonString = jsonString.replace(regex, defaultValue || value);
344
+ });
345
+ const jsonWithDummyData = JSON.parse(jsonString);
346
+ const response: any = await downloadProof({
347
+ json: jsonWithDummyData,
348
+ });
349
+ if (response.status === 200) {
350
+ const binaryData = atob(response.data.data.base64);
351
+ // Create a Uint8Array from the binary data
352
+ const uint8Array = new Uint8Array(binaryData.length);
353
+ for (let i = 0; i < binaryData.length; i++) {
354
+ uint8Array[i] = binaryData.charCodeAt(i);
355
+ }
356
+
357
+ // Create a Blob from the Uint8Array
358
+ const blob = new Blob([uint8Array], { type: 'application/pdf' });
359
+
360
+ // Create an Object URL for the Blob
361
+ const url = URL.createObjectURL(blob);
362
+ downloadPDF(title.substring(0, 20), url);
363
+ dispatch(success('Mailer Proof generated successfully'));
364
+ } else {
365
+ dispatch(
366
+ failure(
367
+ response?.data?.message ||
368
+ response?.message ||
369
+ MESSAGES.DOWNLOAD_ERROR
370
+ )
371
+ );
372
+ }
373
+ } catch (error: any) {
374
+ dispatch(
375
+ failure(
376
+ error?.response?.data?.message ||
377
+ error?.message ||
378
+ 'Error while downloading proof'
379
+ )
380
+ );
381
+ } finally {
382
+ setDownloaingProof(false);
383
+ }
384
+ };
385
+
386
+ const handleEnvelopeProof = async () => {
387
+ try {
388
+ setDownloaingEnvelope(true);
389
+ const response: any = await envelopeProof({
390
+ productId: product.id,
391
+ });
392
+ if (response.status === 200) {
393
+ const binaryData = atob(response.data.data.base64);
394
+ // Create a Uint8Array from the binary data
395
+ const uint8Array = new Uint8Array(binaryData.length);
396
+ for (let i = 0; i < binaryData.length; i++) {
397
+ uint8Array[i] = binaryData.charCodeAt(i);
398
+ }
399
+
400
+ // Create a Blob from the Uint8Array
401
+ const blob = new Blob([uint8Array], { type: 'application/pdf' });
402
+
403
+ // Create an Object URL for the Blob
404
+ const url = URL.createObjectURL(blob);
405
+ downloadPDF(title.substring(0, 20), url);
406
+ dispatch(success('Download Envelope Proof generated successfully'));
407
+ } else {
408
+ dispatch(
409
+ failure(
410
+ response?.data?.message ||
411
+ response?.message ||
412
+ MESSAGES.DOWNLOAD_ERROR
413
+ )
414
+ );
415
+ }
416
+ } catch (error: any) {
417
+ dispatch(
418
+ failure(
419
+ error?.response?.data?.message ||
420
+ error?.message ||
421
+ 'Error while downloading envelope proof'
422
+ )
423
+ );
424
+ } finally {
425
+ setDownloaingEnvelope(false);
426
+ }
427
+ };
428
+
429
+ const handleSave = async () => {
430
+ try {
431
+ const formData = new FormData();
432
+ const allFields = [
433
+ ...defaultFields,
434
+ ...customFields,
435
+ ...Object.values(dynamicFields),
436
+ ...defaultSenderFields,
437
+ ...defaultPropertyFields,
438
+ ...defaultMiscFields,
439
+ ];
440
+ let selectedFields: any = [];
441
+ if (templateType === 'json') {
442
+ let jsonData = store.toJSON();
443
+
444
+ const jsonSize = new Blob([JSON.stringify(jsonData)]).size;
445
+ if (jsonSize > 5242880) {
446
+ dispatch(failure(MESSAGES.TEMPLATE.SIZE_LIMIT_EXCEED));
447
+ return;
448
+ }
449
+
450
+ const hasEmoji = validateEmoji(jsonData.pages);
451
+
452
+ if (hasEmoji) {
453
+ dispatch(failure(MESSAGES.TEMPLATE.EMOJI_NOT_ALLOWED));
454
+ return;
455
+ }
456
+
457
+ if (
458
+ product?.productType === 'Real Penned Letter' &&
459
+ +product.id === 16
460
+ ) {
461
+ const removedUnsupportedBrackets = removeBracketsFromRPL(jsonData);
462
+ jsonData = removedUnsupportedBrackets;
463
+ let clonedJson = JSON.stringify(jsonData)
464
+ .replace(/\(\(/g, '{{')
465
+ .replace(/\)\)/g, '}}');
466
+ jsonData = JSON.parse(clonedJson);
467
+ await store.loadJSON(jsonData);
468
+ }
469
+
470
+ if (product.productType === 'Snap Pack Mailers') {
471
+ const updatedBoxes = changeColorOfBoxesForSnapPack(jsonData);
472
+ jsonData = updatedBoxes;
473
+ }
474
+
475
+ // get all fonts family from json
476
+ const fontFamilies = extractFontFamilies(jsonData?.pages);
477
+
478
+ // extract custom fonts and remove google fonts from that array
479
+ const customFonts = fontFamilies.filter(
480
+ (item: any) => !fonts.includes(item)
481
+ );
482
+
483
+ const availableBase64inJson = jsonData?.fonts?.map(
484
+ (font: any) => font?.fontFamily
485
+ );
486
+
487
+ const unAvailableFonts = customFonts.filter(
488
+ (item: any) => !availableBase64inJson?.includes(item)
489
+ );
490
+
491
+ if (unAvailableFonts?.length) {
492
+ dispatch(
493
+ failure(
494
+ `Please upload ${unAvailableFonts[0]} font in My Fonts section.`
495
+ )
496
+ );
497
+ return;
498
+ }
499
+
500
+ const isGsvValid = validateGSV(jsonData.pages);
501
+
502
+ if (!isGsvValid) {
503
+ dispatch(failure(MESSAGES.TEMPLATE.GSV_RESTRICT_ONE_PER_PAGE));
504
+ return;
505
+ }
506
+
507
+ const hasEmptyQR = !isValidQR(jsonData.pages);
508
+
509
+ if (hasEmptyQR) {
510
+ dispatch(failure(MESSAGES.TEMPLATE.EMPTY_QR_NOT_ALLOWED));
511
+ return;
512
+ }
513
+
514
+ setIsShowModel((prev) => ({ ...prev, loading: true }));
515
+
516
+ const blob = await store.toBlob();
517
+
518
+ if (multiPageTemplates.includes(product.productType)) {
519
+ const backJsonData = { ...jsonData, pages: [jsonData.pages[1]] };
520
+ await store.loadJSON(backJsonData);
521
+ await store.waitLoading();
522
+ const backBlob = await store.toBlob();
523
+ formData.append('backThumbnail', backBlob, 'backLogo.png');
524
+ store.loadJSON(jsonData);
525
+ }
526
+
527
+ const jsonString = JSON.stringify(jsonData);
528
+ const blobData = new Blob([jsonString], { type: 'application/json' });
529
+ formData.append('json', blobData, 'template.json');
530
+ formData.append('thumbnail', blob, 'logo.png');
531
+ selectedFields = allFields.filter((field) =>
532
+ jsonString.includes(field.key)
533
+ );
534
+ if (
535
+ (jsonString.includes('ros_') ||
536
+ jsonString.includes('{{ROS.PROPERTY_OFFER}}')) &&
537
+ rosOfferPercentage != null
538
+ ) {
539
+ formData.append('rosOfferPercentage', rosOfferPercentage);
540
+ }
541
+ }
542
+
543
+ const additionalInfo = {
544
+ hasAdditionalPage: pageCount > 1 && +product?.id === 4 ? true : false,
545
+ };
546
+
547
+ formData.append('additionalInfo', JSON.stringify(additionalInfo));
548
+ formData.append('title', title);
549
+ formData.append('productId', product?.id);
550
+ selectedFields.length
551
+ ? formData.append('fields', JSON.stringify(selectedFields))
552
+ : undefined;
553
+ envelopeType.length
554
+ ? formData.append('envelopeType', envelopeType)
555
+ : undefined;
556
+
557
+ if (onSubmit) {
558
+ const saveTemplate = await onSubmit(formData);
559
+ if (saveTemplate) {
560
+ // dispatch(success(olcTemplate ? 'Template Updated Successfully' : 'Template Created Successfully'));
561
+ handleNavigation();
562
+ }
563
+ } else {
564
+ dispatch(
565
+ failure('Please add onSubmit handler via Props to save template')
566
+ );
567
+ }
568
+ } catch (error) {
569
+ return error;
570
+ } finally {
571
+ setIsShowModel((prev) => ({ ...prev, loading: false }));
572
+ }
573
+ };
574
+
575
+ const handleChangeModel = (
576
+ model: string = '',
577
+ loading: string | null = null
578
+ ) => {
579
+ setIsShowModel((prev) => ({
580
+ ...prev,
581
+ open: !prev.open,
582
+ loading: loading === 'false' ? false : prev.loading,
583
+ model,
584
+ }));
585
+ };
586
+
587
+ return (
588
+ <>
589
+ {currentTheme === 'v2' ? (
590
+ <div className="v2-top-navigation-container">
591
+ <GridContainer style={{ alignItems: 'center' }}>
592
+ <GridItem lg={4} md={4} sm={12} xs={12}>
593
+ <Typography className="create-template-title">
594
+ Create a Template
595
+ </Typography>
596
+ </GridItem>
597
+ <GridItem lg={4} md={3} sm={12} xs={12}>
598
+ <div className="middle-v2">
599
+ {isShowModel.open && isShowModel.model === 'edit-name-modal' ? (
600
+ <div className="input-container">
601
+ <input
602
+ type="text"
603
+ value={templateTitle}
604
+ onChange={(e) => setTemplateTitle(e.target.value)}
605
+ />
606
+ <div className="icon-v2-container">
607
+ <img className="icon-v2" src={CheckIconV2} alt="check" onClick={() => {
608
+ handleEditName();
609
+ }} />
610
+ <img
611
+ src={EditIconV2}
612
+ alt="edit"
613
+ onClick={() => {
614
+ setTemplateTitle(title),
615
+ setIsShowModel((prev) => ({ ...prev, model:'', open: false }));
616
+ }}
617
+ />
618
+ </div>
619
+ </div>
620
+ ) : (
621
+ <Typography>{title}</Typography>
622
+ )}
623
+ {isShowModel.model !== 'edit-name-modal' && (
624
+ <img
625
+ className="pencil-icon"
626
+ src={PencilIcon}
627
+ alt="pencil"
628
+ onClick={() => {
629
+ setIsShowModel((prev) => ({ ...prev, model:'edit-name-modal', open: true }));
630
+ }}
631
+ />
632
+ )}
633
+ </div>
634
+ </GridItem>
635
+ <GridItem lg={4} md={5} sm={12} xs={12}>
636
+ <div className="actionsBtnWrapper right">
637
+ {/* Page Management Controls - Only for Professional Letter Non-Window */}
638
+ {isProfessionalLetterNonWindow() && allowAdditionalPage && (
639
+ <>
640
+ {pageCount === 1 && (
641
+ <div
642
+ className="add-page"
643
+ onClick={handleAddPage}
644
+ title="Add Page"
645
+ >
646
+ <AddIcon />
647
+ </div>
648
+ )}
649
+ {pageCount === 2 && (
650
+ <div
651
+ className="delete-page"
652
+ onClick={handleDeletePage}
653
+ title="Delete Page"
654
+ >
655
+ <DeleteIcon className="delete-icon" />
656
+ </div>
657
+ )}
658
+ </>
659
+ )}
660
+ {olcTemplate &&
661
+ !designerTemplateQuery &&
662
+ onDuplicateTemplate && (
663
+ <div
664
+ className="clone"
665
+ onClick={() =>
666
+ setIsShowModel((prev) => ({
667
+ ...prev,
668
+ open: true,
669
+ model: 'duplicate',
670
+ inputValue: '',
671
+ }))
672
+ }
673
+ >
674
+ <CloneIcon fill="#545454" />
675
+ </div>
676
+ )}
677
+ <GeneralTooltip
678
+ title={MESSAGES.TEMPLATE.DUPLICATE_MODAL.TITLE}
679
+ place="bottom"
680
+ anchorSelect=".clone"
681
+ />
682
+ <GeneralTooltip
683
+ title="Add Page"
684
+ place="bottom"
685
+ anchorSelect=".add-page"
686
+ />
687
+ <GeneralTooltip
688
+ title="Delete Page"
689
+ place="bottom"
690
+ anchorSelect=".delete-page"
691
+ />
692
+ {/* {product?.hasEnvelope && (
693
+ <>
694
+ <div
695
+ className="download-envelope"
696
+ onClick={handleEnvelopeProof}
697
+ >
698
+ {downloadingEnvelope ? (
699
+ <CircularProgress style={progressStyles} />
700
+ ) : (
701
+ <EnvelopeIcon />
702
+ )}
703
+ </div>
704
+ <GeneralTooltip
705
+ title={MESSAGES.TEMPLATE.DOWNLOAD_ENVELOPE_BUTTON}
706
+ place="bottom"
707
+ anchorSelect=".download-envelope"
708
+ />
709
+ </>
710
+ )} */}
711
+ <div className="download" onClick={handleViewProofWithLamda}>
712
+ {downloadingProof ? (
713
+ <CircularProgress style={progressStyles} />
714
+ ) : (
715
+ <img src={DownloadIconV2} alt="download" />
716
+ )}
717
+ </div>
718
+ <GeneralTooltip
719
+ title={MESSAGES.TEMPLATE.DOWNLOAD_PROOF_BUTTON}
720
+ place="bottom"
721
+ anchorSelect=".download"
722
+ />
723
+ <Button
724
+ style={{
725
+ ...buttonStyles,
726
+ border: 'none',
727
+ backgroundColor: 'var(--primary-color)',
728
+ color: '#fff',
729
+ fontSize: '14px',
730
+ fontWeight: '600',
731
+ borderRadius: '4px',
732
+ maxWidth: '140px',
733
+ height: '44px',
734
+ }}
735
+ onClick={() => handleChangeModel('save')}
736
+ >
737
+ {MESSAGES.TEMPLATE.SUBMIT_BUTTON}
738
+ </Button>
739
+ <Button
740
+ style={{
741
+ ...buttonStyles,
742
+ border: '0.5px solid #0000003D',
743
+ color: 'var(--text-color)',
744
+ fontSize: '14px',
745
+ fontWeight: '600',
746
+ borderRadius: '4px',
747
+ maxWidth: '141px',
748
+ height: '45px',
749
+ }}
750
+ onClick={() => handleBackPress()}
751
+ >
752
+ {MESSAGES.TEMPLATE.CANCEL_BUTTON}
753
+ </Button>
754
+ </div>
755
+ </GridItem>
756
+ </GridContainer>
757
+ </div>
758
+ ) : (
759
+ <div className="top-navigation-container">
760
+ <GridContainer style={{ alignItems: 'center' }}>
761
+ <GridItem lg={4} md={4} sm={0} xs={0}></GridItem>
762
+ <GridItem lg={3} md={2} sm={2} xs={12}>
763
+ <div className="middle">
764
+ <Typography>{title}</Typography>
765
+ <div onClick={() => handleChangeModel('edit')}>
766
+ <EditIcon fill="var(--text-color)" />
767
+ </div>
768
+ </div>
769
+ </GridItem>
770
+ <GridItem lg={5} md={6} sm={9} xs={12}>
771
+ <div className="actionsBtnWrapper right">
772
+ {/* Page Management Controls - Only for Professional Letter Non-Window */}
773
+ {isProfessionalLetterNonWindow() && allowAdditionalPage && (
774
+ <>
775
+ {pageCount === 1 && (
776
+ <div
777
+ className="add-page"
778
+ onClick={handleAddPage}
779
+ title="Add Page"
780
+ >
781
+ <AddIcon />
782
+ </div>
783
+ )}
784
+ {pageCount === 2 && (
785
+ <div
786
+ className="delete-page"
787
+ onClick={handleDeletePage}
788
+ title="Delete Page"
789
+ >
790
+ <DeleteIcon className="delete-icon" />
791
+ </div>
792
+ )}
793
+ </>
794
+ )}
795
+ {olcTemplate &&
796
+ !designerTemplateQuery &&
797
+ onDuplicateTemplate && (
798
+ <div
799
+ className="clone"
800
+ onClick={() =>
801
+ setIsShowModel((prev) => ({
802
+ ...prev,
803
+ open: true,
804
+ model: 'duplicate',
805
+ inputValue: '',
806
+ }))
807
+ }
808
+ >
809
+ <CloneIcon fill="#545454" />
810
+ </div>
811
+ )}
812
+ <GeneralTooltip
813
+ title={MESSAGES.TEMPLATE.DUPLICATE_MODAL.TITLE}
814
+ place="bottom"
815
+ anchorSelect=".clone"
816
+ />
817
+ <GeneralTooltip
818
+ title="Add Page"
819
+ place="bottom"
820
+ anchorSelect=".add-page"
821
+ />
822
+ <GeneralTooltip
823
+ title="Delete Page"
824
+ place="bottom"
825
+ anchorSelect=".delete-page"
826
+ />
827
+ {/* {product?.hasEnvelope && (
828
+ <>
829
+ <div
830
+ className="download-envelope"
831
+ onClick={handleEnvelopeProof}
832
+ >
833
+ {downloadingEnvelope ? (
834
+ <CircularProgress style={progressStyles} />
835
+ ) : (
836
+ <EnvelopeIcon />
837
+ )}
838
+ </div>
839
+ <GeneralTooltip
840
+ title={MESSAGES.TEMPLATE.DOWNLOAD_ENVELOPE_BUTTON}
841
+ place="bottom"
842
+ anchorSelect=".download-envelope"
843
+ />
844
+ </>
845
+ )} */}
846
+ <div className="download" onClick={handleViewProofWithLamda}>
847
+ {downloadingProof ? (
848
+ <CircularProgress style={progressStyles} />
849
+ ) : (
850
+ <DownloadIcon />
851
+ )}
852
+ </div>
853
+ <GeneralTooltip
854
+ title={MESSAGES.TEMPLATE.DOWNLOAD_PROOF_BUTTON}
855
+ place="bottom"
856
+ anchorSelect=".download"
857
+ />
858
+ <Button
859
+ style={{
860
+ ...buttonStyles,
861
+ border: '0.5px solid var(--primary-color)',
862
+ color: 'var(--primary-color)',
863
+ }}
864
+ onClick={() => handleBackPress()}
865
+ >
866
+ {MESSAGES.TEMPLATE.CANCEL_BUTTON}
867
+ </Button>
868
+ <Button
869
+ style={{
870
+ ...buttonStyles,
871
+ border: 'none',
872
+ backgroundColor: 'var(--primary-color)',
873
+ color: '#fff',
874
+ }}
875
+ onClick={() => handleChangeModel('save')}
876
+ >
877
+ {MESSAGES.TEMPLATE.SUBMIT_BUTTON}
878
+ </Button>
879
+ </div>
880
+ </GridItem>
881
+ </GridContainer>
882
+ </div>
883
+ )}
884
+
885
+ {showNavigateDialog && (
886
+ <ConfirmNavigateDialog
887
+ open={showNavigateDialog}
888
+ handleClose={() => setShowNavigateDialog(false)}
889
+ handleNavigateAction={() =>
890
+ handleNavigation(createTemplateRoute || '/create-template')
891
+ }
892
+ currentTheme={currentTheme}
893
+ />
894
+ )}
895
+ {isShowModel?.open && isShowModel?.model === 'edit' && (
896
+ <EditTemplateNameModel
897
+ open={isShowModel?.open}
898
+ title={title}
899
+ templateTitle={templateTitle}
900
+ setTemplateTitle={setTemplateTitle}
901
+ handleEditName={handleEditName}
902
+ handleClose={() => handleChangeModel()}
903
+ />
904
+ )}
905
+ {isShowModel.open && isShowModel.model === 'save' && (
906
+ <SaveTemplateModel
907
+ loading={isShowModel.loading}
908
+ open={isShowModel.open}
909
+ handleClose={() => handleChangeModel()}
910
+ handleSave={handleSave}
911
+ store={store}
912
+ allowedAddOns={allowedAddOns}
913
+ currentTheme={currentTheme}
914
+ />
915
+ )}
916
+ {/* Duplicate Template Modal */}
917
+ <DuplicateTemplateModal
918
+ open={isShowModel.open && isShowModel.model === 'duplicate'}
919
+ value={isShowModel.inputValue || ''}
920
+ onChange={(val) =>
921
+ setIsShowModel((prev) => ({
922
+ ...prev,
923
+ inputValue: val,
924
+ }))
925
+ }
926
+ error=""
927
+ title={MESSAGES.TEMPLATE.DUPLICATE_MODAL.TITLE}
928
+ submitButtonText={MESSAGES.TEMPLATE.DUPLICATE_MODAL.SUBMIT_BUTTON}
929
+ onCancel={closeDuplicateModal}
930
+ onDuplicateTemplate={onDuplicateTemplate}
931
+ setIsDuplication={setIsDuplication}
932
+ icon={<CloneIcon fill="var(--primary-color)" />}
933
+ />
934
+ </>
935
+ );
936
+ };
937
+
938
+ export default TopNavigation;