@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,25 @@
1
+ import React from 'react';
2
+
3
+ const ToolArrow = (props: any) => {
4
+ const {style, className} = props;
5
+ return (
6
+ <>
7
+ <svg
8
+ width="19"
9
+ height="17"
10
+ viewBox="0 0 19 17"
11
+ fill="none"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ style={style}
14
+ className={className}
15
+ >
16
+ <path
17
+ d="M10.5699 15.6341C10.0247 16.569 8.67178 16.5631 8.1347 15.6235L0.801114 2.79264C0.264037 1.85297 0.945586 0.684273 2.0279 0.688985L16.8065 0.753326C17.8888 0.758038 18.5602 1.93262 18.0149 2.86758L10.5699 15.6341Z"
18
+ fill="white"
19
+ />
20
+ </svg>
21
+ </>
22
+ );
23
+ };
24
+
25
+ export default ToolArrow;
@@ -0,0 +1,525 @@
1
+ import React, { ReactElement, useEffect, useMemo, useState } from 'react';
2
+
3
+ //hooks
4
+ import { useNavigate } from 'react-router-dom';
5
+ import { useDispatch, useSelector } from 'react-redux';
6
+ import { AppDispatch, RootState } from '../../../redux/store';
7
+
8
+ //actions
9
+ import {
10
+ clearTemplateFields,
11
+ searchAndAdvanceChange,
12
+ selectPostCard,
13
+ selectProduct,
14
+ fetchProducts,
15
+ } from '../../../redux/actions/templateActions';
16
+ import { CLEAR_TEMPLATE } from '../../../redux/actions/action-types';
17
+ import { clearQrFields } from '../../../redux/actions/customQRCodeActions';
18
+
19
+ //utils
20
+ import { sortOrderForTemplatesV2 } from '../../../utils/constants';
21
+ import { removeItem } from '../../../utils/local-storage';
22
+ import { MESSAGES } from '../../../utils/message';
23
+ import { designTypes, envelopeTypes, selfMailerProduct } from '../../../utils/template-builder';
24
+
25
+ // UI Components
26
+ import Typography from '../../GenericUIBlocks/Typography';
27
+ import Input from '../../GenericUIBlocks/Input';
28
+ import CircularProgress from '../../GenericUIBlocks/CircularProgress';
29
+
30
+ // images
31
+ // @ts-ignore
32
+ import Postcard from '../../../assets/images/products/postcard-new.tsx';
33
+ // @ts-ignore
34
+ import ProfessionalLetter from '../../../assets/images/products/professional-new.tsx';
35
+ // @ts-ignore
36
+ import PersonalLetter from '../../../assets/images/products/personal-new.tsx';
37
+ //@ts-ignore
38
+ import TriFoldSelfMailers from '../../../assets/images/templates/tri-fold-self-mailers.tsx';
39
+ //@ts-ignore
40
+ import BiFoldSelfMailers from '../../../assets/images/templates/bi-fold-self-mailers.tsx';
41
+ // @ts-ignore
42
+ import RealPennedLetter from '../../../assets/images/products/real-new.tsx';
43
+ //@ts-ignore
44
+ import SnapPackMailers from '../../../assets/images/templates/snap-pack.tsx';
45
+ // @ts-ignore
46
+ import SelfMailer from '../../../assets/images/products/bi-new.svg';
47
+ // @ts-ignore
48
+ import LeftArrow from '../../../assets/images/products/left-arrow.svg'
49
+ // @ts-ignore
50
+ import RightArrow from '../../../assets/images/products/right-arrow.svg'
51
+
52
+ // @ts-ignore
53
+ import One from '../../../assets/images/thumbnails/one.svg';
54
+
55
+ // styles
56
+ import './styles.scss';
57
+
58
+
59
+ const textStyles = {
60
+ fontSize: '20px',
61
+ fontWeight: '600',
62
+ color: '#000',
63
+ marginBottom: '0',
64
+ }
65
+
66
+ const descriptionStyles = {
67
+ fontSize: '16px',
68
+ fontWeight: '400',
69
+ color: '#00000099',
70
+ marginBottom: '12px',
71
+ }
72
+
73
+ const buttonStyles = {
74
+ width: '100%',
75
+ maxWidth: '157px',
76
+ height: '50px',
77
+ borderRadius: '8px',
78
+ fontSize: '16px',
79
+ fontWeight: '600',
80
+ }
81
+
82
+ const progressStyles = {
83
+ width: '20px',
84
+ height: '20px',
85
+ border: '2px solid var(--primary-color)',
86
+ };
87
+
88
+ const Images: Record<string, ReactElement> = {
89
+ Postcards: <Postcard fill="var(--svg-color)" />,
90
+ 'Professional Letters': <ProfessionalLetter fill="var(--svg-color)" />,
91
+ 'Personal Letters': <PersonalLetter fill="var(--svg-color)" />,
92
+ 'Real Penned Letter': <RealPennedLetter fill="var(--svg-color)" />,
93
+ 'Tri-Fold Self-Mailers': <TriFoldSelfMailers fill="var(--svg-color)" />,
94
+ 'Bi-Fold Self-Mailers': <BiFoldSelfMailers fill="var(--svg-color)" />,
95
+ 'Snap Pack Mailers': <SnapPackMailers fill="var(--svg-color)" />,
96
+ "Self Mailer": <BiFoldSelfMailers fill="var(--svg-color)" />
97
+ };
98
+
99
+ interface CreateTemplateV2Props {
100
+ onReturnAndNavigate?: () => void;
101
+ createTemplateRoute?: string | null;
102
+ templateBuilderRoute?: string | null;
103
+ restrictedProducts?: any;
104
+ disallowedProducts?: string[] | null | undefined;
105
+ currentTheme?: string | null | undefined;
106
+ }
107
+
108
+ const CreateTemplateV2: React.FC<CreateTemplateV2Props> = ({
109
+ onReturnAndNavigate,
110
+ createTemplateRoute,
111
+ templateBuilderRoute,
112
+ restrictedProducts,
113
+ disallowedProducts,
114
+ currentTheme
115
+ }) => {
116
+ const [activeProduct, setActiveProduct] = useState("13");
117
+ const [activeProductType, setActiveProductType] = useState("Postcards");
118
+ const [selectedSize, setSelectedSize] = useState('4x6');
119
+ const [selectedRPLType, setSelectedRPLType] = useState('16');
120
+ const [selectedDesign, setSelectedDesign] = useState<any>(designTypes[0])
121
+ const [envelopeType, setEnvelopeType] = useState<any>(envelopeTypes[0]);
122
+
123
+ const [inputValue, setInputValue] = useState('');
124
+ const [showingFrontImage, setShowingFrontImage] = useState(true);
125
+ const [isError, setIsError] = useState<boolean>(false);
126
+ const [isImageLoading, setIsImageLoading] = useState<boolean>(true);
127
+ const [imageToShow, setImageToShow] = useState(null);
128
+
129
+
130
+ const dispatch: AppDispatch = useDispatch();
131
+ const navigate = useNavigate();
132
+
133
+ const title = useSelector((state: RootState) => state.templates.title) || '';
134
+ const product = useSelector(
135
+ (state: RootState) => state.templates.product
136
+ ) as Record<string, any>;
137
+ const allProducts = useSelector((state: RootState) => state.templates.products);
138
+ const products = useMemo(() => {
139
+ const exists = allProducts.some(p => p.id === "100");
140
+ return exists
141
+ ? allProducts
142
+ : [...allProducts.filter((prod) => prod.id !== '9' && prod.id !== '11'), selfMailerProduct];
143
+ }, [allProducts]);
144
+ const productDetails = useSelector((state: RootState) => state.templates.productDetails);
145
+ const templateType = useSelector(
146
+ (state: RootState) => state.templates.templateType
147
+ );
148
+
149
+ const restrictedSet = new Set(
150
+ (restrictedProducts ?? []).map((id: any) => String(id))
151
+ );
152
+
153
+ const disallowedSet = new Set(disallowedProducts ?? []);
154
+ const sortedProducts = products
155
+ ?.sort((a, b) => {
156
+ const indexA = sortOrderForTemplatesV2.indexOf(a.title === 'Self Mailer' ? a.title : a.productType);
157
+ const indexB = sortOrderForTemplatesV2.indexOf(b.title === 'Self Mailer' ? b.title : b.productType);
158
+ return indexA - indexB;
159
+ })
160
+ .filter((product) => {
161
+ return (
162
+ !restrictedSet.has(String(product.id)) &&
163
+ !disallowedSet.has(product.productType.toLowerCase().replace(/\s+/g, '_'))
164
+ );
165
+ });
166
+
167
+ const filteredEnvelopeTypes = envelopeTypes.filter((type) => {
168
+ return !restrictedProducts?.includes(type.productId);
169
+ });
170
+
171
+ const filteredDesignTypes = designTypes.filter((type) => {
172
+ return !restrictedProducts?.includes(type.productId);
173
+ });
174
+
175
+ const handleNext = () => {
176
+ const trimedTitle = title.trim();
177
+ if (
178
+ !trimedTitle ||
179
+ trimedTitle?.length > 50 ||
180
+ !templateType ||
181
+ !product ||
182
+ (product &&
183
+ product.productType === 'Postcards' &&
184
+ !product?.selectedSize) ||
185
+ (product &&
186
+ product.productType === 'Professional Letters' &&
187
+ !Object.keys(envelopeType).length)
188
+ ) {
189
+ setIsError(true);
190
+ } else {
191
+ let envelope: string | string[] = '';
192
+ if (product.productType === 'Professional Letters') {
193
+ //@ts-ignore
194
+ envelope = envelopeTypes.find(
195
+ //@ts-ignore
196
+ (envelope) => envelope?.label === envelopeType.label
197
+ )?.type;
198
+ }
199
+ dispatch(searchAndAdvanceChange('title', trimedTitle));
200
+ dispatch(searchAndAdvanceChange('envelopeType', envelope));
201
+ navigate(
202
+ templateBuilderRoute ? templateBuilderRoute : '/template-builder'
203
+ );
204
+ }
205
+ };
206
+
207
+ const handleProductChange = (prod: any) => {
208
+ setActiveProduct(prod.id);
209
+ setActiveProductType(prod.title === 'Self Mailer' ? 'Bi-Fold Self-Mailers' : prod.productType);
210
+ setShowingFrontImage(true);
211
+ setIsImageLoading(true);
212
+ dispatch(selectProduct(prod));
213
+ prod.productType !== "Postcards" && setSelectedSize('4x6');
214
+ prod.productType !== "Professional Letters" && setEnvelopeType(envelopeTypes[0]);
215
+ prod.productType !== "Real Penned Letter" && setSelectedRPLType('16');
216
+ prod.title !== "Self Mailer" && setSelectedDesign(designTypes[0]);
217
+ }
218
+
219
+ const handlePostCardSizeChange = (type: any, product: any) => {
220
+ setSelectedSize(type.size);
221
+ handleProductChange(product);
222
+ dispatch(
223
+ selectPostCard(
224
+ {
225
+ ...type,
226
+ size: product.size,
227
+ selectedSize: type.size,
228
+ paper: product.paper,
229
+ finish: product.finish
230
+ },
231
+ 'Postcards'
232
+ )
233
+ )
234
+ }
235
+
236
+ const handleEnvelopeTypeChange = (envelope: any, product: any) => {
237
+ setEnvelopeType(envelope);
238
+ let selectedProduct = null;
239
+ if (envelope?.label === 'Non-Windowed Envelope') {
240
+ selectedProduct = sortedProducts.find((item) => item.windowed === false)
241
+ } else if (envelope?.label === 'Windowed Envelope') {
242
+ selectedProduct = sortedProducts.find((item) => item.windowed === true)
243
+ }
244
+ if (selectedProduct) {
245
+ handleProductChange(selectedProduct);
246
+ }
247
+ }
248
+
249
+ const handleRealPennedLetter = (type: any, product: any) => {
250
+ setSelectedRPLType(type.id);
251
+ handleProductChange(product);
252
+ dispatch(selectPostCard({
253
+ ...product,
254
+ id: type.id,
255
+ size: product.size,
256
+ selectedSize: type.size,
257
+ label: type.label
258
+ }, 'Real Penned Letter'));
259
+ }
260
+
261
+ const handleSliderArrowClick = (direction: string) => {
262
+ if (direction === 'left') {
263
+ setShowingFrontImage(true);
264
+ } else {
265
+ setShowingFrontImage(false);
266
+ }
267
+ setIsImageLoading(true);
268
+ }
269
+
270
+ const handleTemplateNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
271
+ setInputValue(e.target.value);
272
+ dispatch(searchAndAdvanceChange('title', e.target.value));
273
+ }
274
+
275
+ const getCurrentProductDetails = (selectProduct: any) => {
276
+ return productDetails?.find((detail: any) => detail.id === selectProduct.id) || null;
277
+ };
278
+
279
+ useEffect(() => {
280
+ dispatch(fetchProducts());
281
+ dispatch(clearTemplateFields());
282
+ dispatch(clearQrFields());
283
+ removeItem('formData');
284
+ dispatch({ type: CLEAR_TEMPLATE });
285
+ }, []);
286
+
287
+ useEffect(() => {
288
+ if(product && productDetails?.length === 0) setIsImageLoading(false);
289
+ const currentProductDetail = getCurrentProductDetails(product);
290
+ const currentImage = showingFrontImage
291
+ ? currentProductDetail?.thumbnailFrontUrl
292
+ : currentProductDetail?.thumbnailBackUrl;
293
+
294
+ setImageToShow(currentImage);
295
+ }, [product, productDetails, showingFrontImage])
296
+
297
+
298
+ useEffect(() => {
299
+ if (sortedProducts?.length) {
300
+ dispatch(selectProduct(sortedProducts[0]));
301
+ }
302
+ }, [products]);
303
+
304
+ return (
305
+ <div className='create-template-container'>
306
+ <Typography style={{ ...textStyles, marginBottom: '20px' }}>Create a Template</Typography>
307
+ <div className='create-template-content-container'>
308
+ <div className='product-selection-container'>
309
+ <Typography style={descriptionStyles}>Select a Product</Typography>
310
+ <div className='products-container'>
311
+ {sortedProducts &&
312
+ sortedProducts
313
+ ?.filter((prod) => {
314
+ if (restrictedSet.has('2') || restrictedSet.has('4')) {
315
+ return true;
316
+ } else {
317
+ return prod.windowed !== false;
318
+ }
319
+ })
320
+ .map((prod, index) => {
321
+ const ImageOrComponent = Images[prod.productType];
322
+ return (
323
+ <div
324
+ className={`product-card ${prod.productType === activeProductType ? 'active' : ''}`}
325
+ key={index}
326
+ onClick={() => handleProductChange(prod)}
327
+ >
328
+ {typeof ImageOrComponent === 'string' ? (
329
+ <img src={ImageOrComponent} alt="Product" />
330
+ ) : (
331
+ ImageOrComponent
332
+ )}
333
+ <Typography style={{ ...textStyles, fontSize: '16px', fontWeight: '500', color: '#000' }}>{prod.title === 'Self Mailer' ? prod.title : prod.productType}</Typography>
334
+ </div>
335
+ );
336
+ })}
337
+ </div>
338
+ {product && product?.productType === 'Postcards' && product?.size && (
339
+ <div className='size-selection-container'>
340
+ <Typography style={descriptionStyles}>Postcard Size</Typography>
341
+ <div className='radio-buttons-container'>
342
+ {product?.size
343
+ .map((type: any, index: any) => {
344
+ const size = type?.label?.split('x') || type?.size?.split('x');
345
+ return (
346
+ <label key={index} className={`radio-button-wrapper ${selectedSize === type.size ? 'selected' : ''}`}>
347
+ <input type="radio" name="postcardSize" value={type.size} checked={selectedSize === type.size} onChange={() => handlePostCardSizeChange(type, product)} className="radio-input" />
348
+ <span className="radio-button"></span>
349
+
350
+ <Typography
351
+ style={{
352
+ fontSize: '16px',
353
+ fontWeight: 400,
354
+ color: '#000',
355
+ margin: 0,
356
+ }}
357
+ >
358
+ {`${size[0]}" x ${size[1]}"`}
359
+ </Typography>
360
+ </label>
361
+ )
362
+ })}
363
+ </div>
364
+ </div>
365
+ )}
366
+ {product && (product?.title === 'Self Mailer' || product?.productType === "Bi-Fold Self-Mailers" || product?.productType === "Tri-Fold Self-Mailers") && (
367
+ <div className='size-selection-container'>
368
+ <Typography style={descriptionStyles}>Design Format</Typography>
369
+ <div className='radio-buttons-container'>
370
+ {filteredDesignTypes.map((design: any, index: any) => {
371
+ return (
372
+ <label key={index} className={`radio-button-wrapper ${selectedDesign.id === design.id ? 'selected' : ''}`}>
373
+ <input type="radio" name="postcardSize" value={design.type} checked={selectedDesign.id === design.id} onChange={() => { setSelectedDesign(design), handleProductChange(selfMailerProduct?.types[design.id]) }} className="radio-input" />
374
+ <span className="radio-button"></span>
375
+
376
+ <Typography
377
+ style={{
378
+ fontSize: '16px',
379
+ fontWeight: 400,
380
+ color: '#000',
381
+ margin: 0,
382
+ }}
383
+ >
384
+ {design?.label}
385
+ </Typography>
386
+ </label>
387
+ )
388
+ })}
389
+ </div>
390
+ </div>
391
+ )}
392
+ {product && product.productType === 'Professional Letters' && (
393
+ <div className='size-selection-container'>
394
+ <Typography style={descriptionStyles}>Envelope Type</Typography>
395
+ <div className='radio-buttons-container'>
396
+ {filteredEnvelopeTypes.map((envelope) => (
397
+ <label key={envelope.id} className={`radio-button-wrapper ${envelopeType?.id === envelope.id ? 'selected' : ''}`}>
398
+ <input type="radio" name="postcardSize" value={envelope.type} checked={envelopeType?.id === envelope.id} onChange={() => handleEnvelopeTypeChange(envelope, product)} className="radio-input" />
399
+ <span className="radio-button"></span>
400
+ <Typography style={{ fontSize: '16px', fontWeight: '400', color: 'var(--text-color)', margin: 0 }}>{envelope.label}</Typography>
401
+ </label>
402
+ ))}
403
+ </div>
404
+ </div>
405
+ )}
406
+ {product?.productType === 'Real Penned Letter' && (
407
+ <div className='size-selection-container'>
408
+ <Typography style={descriptionStyles}>Design Format</Typography>
409
+ <div className='radio-buttons-container'>
410
+ {product?.size?.map((type: any) => (
411
+ <label key={type.id} className={`radio-button-wrapper ${selectedRPLType === type.id ? 'selected' : ''}`}>
412
+ <input type="radio" name="postcardSize" value={type.id} checked={selectedRPLType === type.id} onChange={() => handleRealPennedLetter(type, product)} className="radio-input" />
413
+ <span className="radio-button"></span>
414
+ <Typography style={{ fontSize: '16px', fontWeight: '400', color: 'var(--text-color)', margin: 0 }}>{type.title}</Typography>
415
+ </label>
416
+ ))}
417
+ </div>
418
+ </div>
419
+ )}
420
+ <div>
421
+ <Input
422
+ label='Template Name'
423
+ type="text"
424
+ placeholder='Untitled Name'
425
+ className="NewDesignSearch"
426
+ currentTheme={currentTheme}
427
+ value={inputValue}
428
+ onChange={handleTemplateNameChange}
429
+ error={
430
+ !title.trim() && isError
431
+ ? MESSAGES.TEMPLATE.NAME_REQUIRED
432
+ : title.length > 50 && isError
433
+ ? MESSAGES.TEMPLATE.NAME_LESS_50
434
+ : ''
435
+ }
436
+ />
437
+ </div>
438
+ </div>
439
+ <div className='product-thumbnail-container'>
440
+ <div className='product-thumbnail-card'>
441
+ <div className='thumbail-slider'>
442
+ <div className='thumbail-slider-image'>
443
+ {isImageLoading && (
444
+ <div className='image-loader'>
445
+ <CircularProgress style={progressStyles} />
446
+ </div>
447
+ )}
448
+ {!isImageLoading && !imageToShow ? (
449
+ <img
450
+ src={One}
451
+ alt={`Dummy Product thumbnail`}
452
+ onLoad={() => setIsImageLoading(false)}
453
+ onError={() => setIsImageLoading(false)}
454
+ style={{ display: isImageLoading ? 'none' : 'block' }}
455
+ />
456
+
457
+ ) : (
458
+ <img
459
+ key={showingFrontImage ? 'front' : 'back'}
460
+ //@ts-ignore
461
+ src={imageToShow}
462
+ alt={`Product ${showingFrontImage ? 'front' : 'back'} thumbnail`}
463
+ onLoad={() => setIsImageLoading(false)}
464
+ onError={() => setIsImageLoading(false)}
465
+ style={{ display: isImageLoading ? 'none' : 'block' }}
466
+ />
467
+ )}
468
+ {(() => {
469
+ const currentProductDetail = getCurrentProductDetails(product);
470
+
471
+ if (!currentProductDetail || !currentProductDetail?.thumbnailBackUrl) {
472
+ return null;
473
+ }
474
+
475
+ return (
476
+ <>
477
+ <div
478
+ className={`slider-arrow-left ${showingFrontImage ? 'disabled' : ''}`}
479
+ onClick={() => !showingFrontImage && handleSliderArrowClick('left')}
480
+ >
481
+ <img src={LeftArrow} alt='left' />
482
+ </div>
483
+ <div
484
+ className={`slider-arrow-right ${!showingFrontImage ? 'disabled' : ''}`}
485
+ onClick={() => showingFrontImage && handleSliderArrowClick('right')}
486
+ >
487
+ <img src={RightArrow} alt='right' />
488
+ </div>
489
+ </>
490
+ );
491
+ })()}
492
+ </div>
493
+ </div>
494
+ </div>
495
+ <div className='product-thumbnail-details'>
496
+ <Typography style={{ ...textStyles, fontSize: '16px' }}>
497
+ Size:{' '}
498
+ <span>
499
+ {(() => {
500
+ const size = product?.label?.split('x') || product?.selectedSize?.split('x');
501
+ return size?.length ? `${size[0] || ''}" x ${size[1] || ''}"` : product?.selectedSize;
502
+ })() || product?.selectedSize || '-'}
503
+ </span>
504
+ </Typography>
505
+ <Typography style={{ ...textStyles, fontSize: '16px' }}>
506
+ Paper: <span>{product?.paper}</span>
507
+ </Typography>
508
+ {product?.finish && <Typography style={{ ...textStyles, fontSize: '16px' }}>
509
+ Finish: <span>{product?.finish}</span>
510
+ </Typography>}
511
+ {product?.envelopeOptions && <Typography style={{ ...textStyles, fontSize: '16px' }}>
512
+ Envelope: <span>{product?.envelopeOptions}</span>
513
+ </Typography>}
514
+ </div>
515
+ </div>
516
+ </div>
517
+ <div className='buttons-container'>
518
+ <button onClick={handleNext}>Next</button>
519
+ <button onClick={() => onReturnAndNavigate ? onReturnAndNavigate() : navigate(createTemplateRoute || '/create-template')}>Cancel</button>
520
+ </div>
521
+ </div>
522
+ )
523
+ }
524
+
525
+ export default CreateTemplateV2;