@capillarytech/creatives-library 7.10.39 → 7.10.41

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 (38) hide show
  1. package/containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +0 -2
  2. package/containers/Email/index.js +2 -3
  3. package/index.js +6 -0
  4. package/package.json +1 -1
  5. package/routes.js +5 -0
  6. package/services/api.js +6 -1
  7. package/v2Components/TemplatePreview/_templatePreview.scss +7 -0
  8. package/v2Components/TemplatePreview/assets/images/whatsapp_mobile_android.svg +2041 -0
  9. package/v2Components/TemplatePreview/index.js +57 -3
  10. package/v2Components/TemplatePreview/messages.js +8 -0
  11. package/v2Containers/Assets/Gallery/tests/__snapshots__/reducer.test.js.snap +0 -2
  12. package/v2Containers/Assets/images/whatsappIllustration.png +0 -0
  13. package/v2Containers/CreativesContainer/SlideBoxContent.js +31 -2
  14. package/v2Containers/CreativesContainer/SlideBoxHeader.js +31 -3
  15. package/v2Containers/CreativesContainer/constants.js +1 -0
  16. package/v2Containers/CreativesContainer/messages.js +4 -0
  17. package/v2Containers/Email/index.js +1 -3
  18. package/v2Containers/Line/Container/index.js +1 -1
  19. package/v2Containers/Templates/_templates.scss +43 -0
  20. package/v2Containers/Templates/actions.js +18 -10
  21. package/v2Containers/Templates/constants.js +3 -1
  22. package/v2Containers/Templates/index.js +296 -44
  23. package/v2Containers/Templates/messages.js +32 -0
  24. package/v2Containers/Templates/reducer.js +3 -1
  25. package/v2Containers/TemplatesV2/index.js +2 -0
  26. package/v2Containers/TemplatesV2/messages.js +4 -0
  27. package/v2Containers/Whatsapp/actions.js +34 -0
  28. package/v2Containers/Whatsapp/constants.js +125 -0
  29. package/v2Containers/Whatsapp/index.js +831 -0
  30. package/v2Containers/Whatsapp/index.scss +56 -0
  31. package/v2Containers/Whatsapp/messages.js +221 -0
  32. package/v2Containers/Whatsapp/reducer.js +54 -0
  33. package/v2Containers/Whatsapp/sagas.js +77 -0
  34. package/v2Containers/Whatsapp/selectors.js +12 -0
  35. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +120831 -0
  36. package/v2Containers/Whatsapp/tests/index.test.js +132 -0
  37. package/v2Containers/Whatsapp/tests/mockData.js +10 -0
  38. package/v2Containers/Whatsapp/utils.js +106 -0
@@ -0,0 +1,831 @@
1
+ /* eslint-disable no-undef */
2
+ import React, { useState, useEffect } from 'react';
3
+ import { bindActionCreators } from 'redux';
4
+ import { createStructuredSelector } from 'reselect';
5
+ import { injectIntl, FormattedMessage } from 'react-intl';
6
+ import { get, isEmpty, cloneDeep } from 'lodash';
7
+ import styled from 'styled-components';
8
+ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
9
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
10
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
11
+ import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
12
+ import CapTooltipWithInfo from '@capillarytech/cap-ui-library/CapTooltipWithInfo';
13
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
14
+ import CapSelect from '@capillarytech/cap-ui-library/CapSelect';
15
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
16
+ import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
17
+ import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
18
+ import CapError from '@capillarytech/cap-ui-library/CapError';
19
+ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
20
+ import CapButton from '@capillarytech/cap-ui-library/CapButton';
21
+ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
22
+ import CapAlert from '@capillarytech/cap-ui-library/CapAlert';
23
+ import moment from 'moment';
24
+ import {
25
+ CAP_SPACE_04,
26
+ CAP_SPACE_16,
27
+ CAP_SPACE_24,
28
+ CAP_SPACE_32,
29
+ CAP_WHITE,
30
+ } from '@capillarytech/cap-ui-library/styled/variables';
31
+ import { makeSelectWhatsapp, makeSelectAccount } from './selectors';
32
+ import * as WhatsappActions from './actions';
33
+ import './index.scss';
34
+ import {
35
+ UNSUBSCRIBE_TEXT_LENGTH,
36
+ TEMPLATE_MESSAGE_MAX_LENGTH,
37
+ WHATSAPP,
38
+ CATEGORY_OPTIONS,
39
+ WHATSAPP_STATUSES,
40
+ TAG,
41
+ EMBEDDED,
42
+ DEFAULT,
43
+ FULL,
44
+ ALL,
45
+ LIBRARY,
46
+ } from './constants';
47
+ import messages from './messages';
48
+ import withCreatives from '../../hoc/withCreatives';
49
+ import TemplatePreview from '../../v2Components/TemplatePreview';
50
+ import TagList from '../TagList';
51
+ import { makeSelectMetaEntities, setInjectedTags } from '../Cap/selectors';
52
+
53
+ let varMap = {};
54
+ let editContent = {};
55
+
56
+ export const Whatsapp = (props) => {
57
+ const {
58
+ intl,
59
+ actions,
60
+ isFullMode,
61
+ onCreateComplete,
62
+ handleClose,
63
+ params,
64
+ templateData = {},
65
+ editData = {},
66
+ accountData = {},
67
+ globalActions,
68
+ location,
69
+ getDefaultTags,
70
+ supportedTags,
71
+ metaEntities,
72
+ injectedTags,
73
+ } = props || {};
74
+ const { formatMessage } = intl;
75
+ const { TextArea } = CapInput;
76
+ const [templateName, setTemplateName] = useState('');
77
+ const [templateNameError, setTemplateNameError] = useState(false);
78
+ const [templateCategory, setTemplateCategory] = useState(
79
+ formatMessage(messages.select),
80
+ );
81
+ const [templateMessage, setTemplateMessage] = useState('');
82
+ const [templateMessageError, setTemplateMessageError] = useState(false);
83
+ const [addedVarCount, setAddedVarCount] = useState(0);
84
+ const [accountId, setAccountId] = useState('');
85
+ const [accessToken, setAccessToken] = useState('');
86
+ const [accountName, setAccountName] = useState('');
87
+ const [spin, setSpin] = useState(false);
88
+ //for edit only
89
+ const [isEditFlow, setEditFlow] = useState(false);
90
+ const [templateDate, setTemplateDate] = useState('');
91
+ const [templateStatus, setTemplateStatus] = useState(
92
+ WHATSAPP_STATUSES.unsubmitted,
93
+ );
94
+ const [tempMsgArray, updateTempMsgArray] = useState([]);
95
+ const [updatedSmsEditor, setUpdatedSmsEditor] = useState([]);
96
+ //for tag only
97
+ const [tags, updateTags] = useState([]);
98
+ const [textAreaId, updateTextAreaId] = useState();
99
+
100
+ const validVarRegex = /{{([1-9]|1[0-9])}}/g;
101
+
102
+ const WhatsappFooter = styled.div`
103
+ background-color: ${CAP_WHITE};
104
+ position: fixed;
105
+ bottom: 0;
106
+ width: 100%;
107
+ margin-left: -32px;
108
+ padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
109
+
110
+ .ant-btn {
111
+ margin-right: ${CAP_SPACE_16};
112
+ }
113
+ }
114
+ `;
115
+ //edit
116
+ //gets account details
117
+ useEffect(() => {
118
+ const accountObj = accountData.selectedWhatsappAccount || {};
119
+ if (!isEmpty(accountObj)) {
120
+ setAccountId(get(accountObj, `sourceAccountIdentifier`, ''));
121
+ setAccessToken(get(accountObj, `configs.accessToken`, ''));
122
+ setAccountName(get(accountObj, `name`, ''));
123
+ }
124
+ }, [accountData.selectedWhatsappAccount]);
125
+
126
+ //gets template details
127
+ const paramObj = params || {};
128
+ useEffect(() => {
129
+ const { id } = paramObj;
130
+ if (id && !get(templateData, `versions.base.content`)) {
131
+ setSpin(true);
132
+ actions.getTemplateDetails(id);
133
+ setEditFlow(true);
134
+ }
135
+ //cleanup code
136
+ return () => {
137
+ actions.resetEditTemplate();
138
+ varMap = {};
139
+ };
140
+ }, [paramObj.id]);
141
+
142
+ useEffect(() => {
143
+ editContent =
144
+ get(templateData, `versions.base.content.whatsapp`) ||
145
+ get(editData, `templateDetails.versions.base.content.whatsapp`) ||
146
+ {};
147
+ if (editContent && !isEmpty(editContent)) {
148
+ const editMessageTitle =
149
+ (templateData || {}).name || get(editData, 'templateDetails.name');
150
+ const createdAt =
151
+ (templateData || {}).createdAt ||
152
+ get(editData, 'templateDetails.createdAt');
153
+ setTemplateName(editMessageTitle);
154
+ setTemplateDate(createdAt);
155
+ setTemplateCategory(get(editContent, `category`, ''));
156
+ setTemplateStatus(
157
+ get(editContent, `status`, WHATSAPP_STATUSES.unsubmitted),
158
+ );
159
+ computeTempMsgArray();
160
+ }
161
+ }, [editData.templateDetails || templateData]);
162
+
163
+ const computeTempMsgArray = () => {
164
+ let msg = get(editContent, `languages[0].content`, '');
165
+ const validVarArr = msg.match(validVarRegex) || [];
166
+ const templateMessageArray = [];
167
+ msg = msg.slice(2, -1);
168
+ msg = msg.replace(
169
+ `Click ${validVarArr[validVarArr.length - 1]} to unsubscribe`,
170
+ '',
171
+ );
172
+ validVarArr.pop();
173
+ while (msg.length !== 0) {
174
+ const index = msg.indexOf(validVarArr[0]);
175
+ if (index !== -1) {
176
+ templateMessageArray.push(msg.substring(0, index));
177
+ templateMessageArray.push(validVarArr[0]);
178
+ msg = msg.substring(index + validVarArr[0].length, msg.length);
179
+ validVarArr.shift();
180
+ } else {
181
+ templateMessageArray.push(msg);
182
+ break;
183
+ }
184
+ }
185
+ updateTempMsgArray(templateMessageArray.filter((i) => i === 0 || i));
186
+ //stop spinner
187
+ setSpin(false);
188
+ };
189
+
190
+ useEffect(() => {
191
+ if (tempMsgArray.length !== 0) {
192
+ const { varMapped = {} } = editContent;
193
+ if (!isEmpty(varMapped)) {
194
+ varMap = cloneDeep(varMapped);
195
+ } else {
196
+ //computing and setting varMap for first edit
197
+ for (let i = 0; i < tempMsgArray.length; i += 1) {
198
+ if (tempMsgArray[i].match(validVarRegex)?.length > 0) {
199
+ varMap[`${tempMsgArray[i]}_${i}`] = '';
200
+ }
201
+ }
202
+ }
203
+ //setting updatedSmsEditor based on varMap
204
+ const arr = [...tempMsgArray];
205
+ for (const key in varMap) {
206
+ if (varMap[key] !== '') {
207
+ arr[key.slice(key.indexOf('_') + 1)] = varMap[key];
208
+ }
209
+ }
210
+ setUpdatedSmsEditor(arr);
211
+ }
212
+ }, [tempMsgArray]);
213
+
214
+ // tag Code start from here
215
+ useEffect(() => {
216
+ //fetching tags
217
+ const { type, module } = location.query || {};
218
+ const isEmbedded = type === EMBEDDED;
219
+ const query = {
220
+ layout: 'SMS',
221
+ type: TAG,
222
+ context: isEmbedded ? module : DEFAULT,
223
+ embedded: isEmbedded ? type : FULL,
224
+ };
225
+ if (getDefaultTags) {
226
+ query.context = getDefaultTags;
227
+ }
228
+ globalActions.fetchSchemaForEntity(query);
229
+ }, []);
230
+
231
+ useEffect(() => {
232
+ let tag =
233
+ metaEntities && metaEntities.tags ? metaEntities.tags.standard : [];
234
+ const { type, module } = location.query || {};
235
+ if (type === EMBEDDED && module === LIBRARY && !getDefaultTags) {
236
+ tag = supportedTags;
237
+ }
238
+ updateTags(tag);
239
+ }, [metaEntities]);
240
+
241
+ const handleOnTagsContextChange = (data) => {
242
+ const { type } = location.query || {};
243
+ const isEmbedded = type === EMBEDDED;
244
+ const query = {
245
+ layout: 'SMS',
246
+ type: TAG,
247
+ context:
248
+ (data || '').toLowerCase() === ALL
249
+ ? DEFAULT
250
+ : (data || '').toLowerCase(),
251
+ embedded: isEmbedded ? type : FULL,
252
+ };
253
+ globalActions.fetchSchemaForEntity(query);
254
+ };
255
+
256
+ const onTagSelect = (data) => {
257
+ if (varMap && updatedSmsEditor) {
258
+ let numId = Number(textAreaId?.slice(textAreaId?.indexOf('_') + 1));
259
+ if (numId !== NaN) {
260
+ const arr = [...updatedSmsEditor];
261
+ //when trying to insert tag in empty textarea,{#var#} is replaced with "" and then tag is added
262
+ if (arr[numId]?.match(validVarRegex)?.length > 0) {
263
+ arr[numId] = '';
264
+ }
265
+ const messageData = `${arr[numId]}{{${data}}}`;
266
+ arr[numId] = messageData;
267
+ varMap[textAreaId] = messageData;
268
+ setUpdatedSmsEditor(arr);
269
+ }
270
+ }
271
+ };
272
+
273
+ //setting the id of currently selected text area, is used onTagSelect
274
+ const setTextAreaId = ({ target: { id } }) => {
275
+ updateTextAreaId(id);
276
+ };
277
+ // tag Code end
278
+
279
+ //create methods start
280
+ const renderTemplateCategoryLabel = (tooltipLabel, title) => (
281
+ <CapRow>
282
+ <CapColumn span={23}>{title}</CapColumn>
283
+ <CapColumn span={1}>
284
+ <CapTooltipWithInfo
285
+ infoIconProps={{
286
+ style: { marginLeft: CAP_SPACE_16 },
287
+ }}
288
+ autoAdjustOverflow
289
+ placement="right"
290
+ title={tooltipLabel}
291
+ />
292
+ </CapColumn>
293
+ </CapRow>
294
+ );
295
+
296
+ const templateCategoryOptions = CATEGORY_OPTIONS.map((option) => ({
297
+ value: option.value,
298
+ label: renderTemplateCategoryLabel(option.tooltipLabel, option.label),
299
+ }));
300
+
301
+ const mediaRadioOptions = [
302
+ {
303
+ value: 'text',
304
+ label: formatMessage(messages.mediaTextMessage),
305
+ },
306
+ {
307
+ value: 'image',
308
+ label: (
309
+ <CapTooltip title={formatMessage(messages.disabledMediaTooltip)}>
310
+ {formatMessage(messages.mediaImage)}
311
+ </CapTooltip>
312
+ ),
313
+ disabled: true,
314
+ },
315
+ {
316
+ value: 'video',
317
+ label: (
318
+ <CapTooltip title={formatMessage(messages.disabledMediaTooltip)}>
319
+ {formatMessage(messages.mediaVideo)}
320
+ </CapTooltip>
321
+ ),
322
+ disabled: true,
323
+ },
324
+ ];
325
+
326
+ const renderLabel = (value) => (
327
+ <CapHeading type="h4" className="whatsapp-render-heading">
328
+ {formatMessage(messages[value])}
329
+ </CapHeading>
330
+ );
331
+
332
+ const renderUnsubscribeText = () => (
333
+ <>
334
+ <CapColumn span={12}>
335
+ <CapTooltip
336
+ placement="bottom"
337
+ title={formatMessage(messages.unsubscribeTextTooltip)}
338
+ >
339
+ <CapHeading
340
+ className={
341
+ !isEditFlow
342
+ ? 'whatsapp-create-render-unsubscribe-text'
343
+ : 'whatsapp-edit-render-unsubscribe-text'
344
+ }
345
+ >
346
+ {formatMessage(messages.templateMessageUnsubscribeText)}
347
+ </CapHeading>
348
+ </CapTooltip>
349
+ </CapColumn>
350
+ <CapColumn span={12}></CapColumn>
351
+ </>
352
+ );
353
+
354
+ const renderMessageLength = () => (
355
+ <CapHeading type="h6" className="whatsapp-render-message-length">
356
+ {formatMessage(messages.templateMessageLength, {
357
+ currentLength: UNSUBSCRIBE_TEXT_LENGTH + templateMessage?.length,
358
+ maxLength: TEMPLATE_MESSAGE_MAX_LENGTH,
359
+ })}
360
+ </CapHeading>
361
+ );
362
+
363
+ const onTemplateNameChange = ({ target: { value } }) => {
364
+ setTemplateName(value);
365
+ templateNameErrorHandler(value);
366
+ };
367
+
368
+ const templateNameErrorHandler = (value) => {
369
+ let errorMessage = false;
370
+ //regex to accept only lowercase alphanumeric characters and underscores
371
+ const templateNameRegex = /^[a-z0-9_]+$/;
372
+ if (value === '') {
373
+ errorMessage = formatMessage(messages.emptyTemplateNameErrorMessage);
374
+ } else if (!templateNameRegex.test(value)) {
375
+ errorMessage = formatMessage(messages.templateNameRegexErrorMessage);
376
+ }
377
+ setTemplateNameError(errorMessage);
378
+ };
379
+
380
+ const onTemplateCategoryChange = (value) => {
381
+ setTemplateCategory(value);
382
+ };
383
+
384
+ const onTemplateMessageChange = ({ target: { value } }) => {
385
+ const error = templateMessageErrorHandler(value);
386
+ setTemplateMessage(value);
387
+ setTemplateMessageError(error);
388
+ };
389
+
390
+ const templateMessageErrorHandler = (value) => {
391
+ let errorMessage = false;
392
+ if (value === '') {
393
+ errorMessage = formatMessage(messages.emptyTemplateMessageErrorMessage);
394
+ } else if (
395
+ UNSUBSCRIBE_TEXT_LENGTH + value?.length >
396
+ TEMPLATE_MESSAGE_MAX_LENGTH
397
+ ) {
398
+ errorMessage = formatMessage(messages.templateMessageLengthError);
399
+ } else {
400
+ const validVarArr = value.match(validVarRegex) || [];
401
+ const validVarSet = [...new Set(validVarArr)];
402
+
403
+ const invalidVarRegex = /{{(.+?)}}/g;
404
+ const invalidVarArr = value.match(invalidVarRegex) || [];
405
+ const invalidVarSet = [...new Set(invalidVarArr)];
406
+
407
+ const noContentBetweenVars = /}}[^a-zA-Z]*{{/g;
408
+
409
+ if (validVarArr?.length > 0 || invalidVarArr?.length > 0) {
410
+ if (validVarArr?.length !== validVarSet?.length) {
411
+ //checks for repetations like Hi {{1}}, offer for you {{1}}
412
+ errorMessage = formatMessage(messages.repetativeVars);
413
+ } else if (invalidVarSet?.length !== validVarSet?.length) {
414
+ //checks for invalid vars like Hi {{abcd}}, offer for you {{^_^}}
415
+ errorMessage = formatMessage(messages.unknownVars);
416
+ } else if (value.match(noContentBetweenVars)?.length > 0) {
417
+ //checks for text between vars like Hi {{1}}{{2}}
418
+ errorMessage = formatMessage(messages.noContentBetweenVars);
419
+ } else {
420
+ //checks if vars are added sequentially like, Hi {{1}}, offer for you {{2}} today {{3}}
421
+ const checkSequence = [...validVarSet].filter(
422
+ (validVar, index) => `{{${index + 1}}}` !== validVar,
423
+ );
424
+ if (checkSequence?.length > 0) {
425
+ errorMessage = formatMessage(messages.sequenceVars);
426
+ } else {
427
+ setAddedVarCount(validVarSet?.length || 0);
428
+ }
429
+ }
430
+ }
431
+ }
432
+ return errorMessage;
433
+ };
434
+
435
+ const createPayload = () => ({
436
+ name: templateName,
437
+ versions: {
438
+ base: {
439
+ content: {
440
+ whatsapp: {
441
+ category: templateCategory,
442
+ languages: [
443
+ {
444
+ language: 'en',
445
+ content: `$'${templateMessage}\nClick {{${
446
+ addedVarCount + 1
447
+ }}} to unsubscribe'`,
448
+ },
449
+ ],
450
+ mediaType: 'text',
451
+ varMapped: {},
452
+ accountId,
453
+ accessToken,
454
+ accountName,
455
+ },
456
+ },
457
+ },
458
+ },
459
+ type: WHATSAPP,
460
+ });
461
+
462
+ const actionCallback = ({ errorMessage, resp }) => {
463
+ const error = errorMessage?.message || errorMessage;
464
+ if (!error) {
465
+ CapNotification.success({
466
+ message: formatMessage(messages.whatsappCreateNotification, {
467
+ name: templateName,
468
+ }),
469
+ });
470
+ actions.clearCreateResponse();
471
+ } else {
472
+ CapNotification.error({
473
+ message: error,
474
+ });
475
+ }
476
+ };
477
+
478
+ const createApprovalHandler = () => {
479
+ setSpin(true);
480
+ actions.createWhatsappTemplate(createPayload(), (resp, errorMessage) => {
481
+ actionCallback({ resp, errorMessage });
482
+ if (!errorMessage) {
483
+ onCreateComplete();
484
+ } else {
485
+ setSpin(false);
486
+ }
487
+ });
488
+ };
489
+
490
+ const onDoneCallback = () => {
491
+ if (isFullMode) {
492
+ return createApprovalHandler;
493
+ }
494
+ };
495
+
496
+ const isDisableDone = () => {
497
+ //if template name is not entered
498
+ if (templateName.trim() === '' || templateNameError) {
499
+ return true;
500
+ }
501
+ //if template category is not selected
502
+ if (templateCategory === 'Select') {
503
+ return true;
504
+ }
505
+ //if template message is not entered
506
+ if (templateMessage.trim() === '' || templateMessageError) {
507
+ return true;
508
+ }
509
+ return false;
510
+ };
511
+
512
+ const createModeContent = (
513
+ <>
514
+ {/* template name */}
515
+ <CapHeader
516
+ title={
517
+ <CapHeading type="h4">
518
+ {formatMessage(messages.templateNameLabel)}
519
+ <CapTooltipWithInfo
520
+ infoIconProps={{
521
+ style: { marginLeft: CAP_SPACE_04 },
522
+ }}
523
+ autoAdjustOverflow
524
+ title={<FormattedMessage {...messages.templateNameTooltip} />}
525
+ />
526
+ </CapHeading>
527
+ }
528
+ description={
529
+ <CapLabel className="whatsapp-template-name-desc">
530
+ {formatMessage(messages.templateNameDesc)}
531
+ </CapLabel>
532
+ }
533
+ />
534
+ <CapInput
535
+ id={`whatsapp_template_name_input`}
536
+ onChange={onTemplateNameChange}
537
+ errorMessage={templateNameError}
538
+ placeholder={formatMessage(messages.templateNamePlaceholder)}
539
+ defaultValue={templateName || ''}
540
+ value={templateName || ''}
541
+ size="default"
542
+ />
543
+ {/* template category */}
544
+ {renderLabel('templateCategoryLabel')}
545
+ <CapSelect
546
+ id={'select-whatsapp-category'}
547
+ options={templateCategoryOptions || []}
548
+ onChange={onTemplateCategoryChange}
549
+ value={templateCategory}
550
+ />
551
+ {/* template language */}
552
+ {renderLabel('messageLanguageLabel')}
553
+ <CapInput
554
+ id={`whatsapp_template_language_input`}
555
+ defaultValue={'English'}
556
+ size="default"
557
+ disabled={true}
558
+ />
559
+ {/* template mdeia type */}
560
+ {renderLabel('mediaLabel')}
561
+ <CapRadioGroup options={mediaRadioOptions || []} defaultValue={'text'} />
562
+ {/* template message create flow */}
563
+ <CapHeading type="h4" className="whatsapp-render-heading">
564
+ {formatMessage(messages.templateMessageLabel)}
565
+ <CapTooltipWithInfo
566
+ placement="right"
567
+ infoIconProps={{
568
+ style: { marginLeft: CAP_SPACE_04 },
569
+ }}
570
+ autoAdjustOverflow
571
+ title={
572
+ <FormattedMessage
573
+ {...messages.templateMessageTooltip}
574
+ values={{
575
+ br: <br />,
576
+ var: '{{1}}',
577
+ }}
578
+ />
579
+ }
580
+ />
581
+ </CapHeading>
582
+ <CapRow className="whatsapp-create-template-message-input">
583
+ <TextArea
584
+ id={`whatsapp-create-template-message-input`}
585
+ autosize={{ minRows: 3, maxRows: 5 }}
586
+ placeholder={formatMessage(messages.templateMessagePlaceholder)}
587
+ onChange={onTemplateMessageChange}
588
+ errorMessage={
589
+ templateMessageError && (
590
+ <CapError className="whatsapp-template-message-error">
591
+ {templateMessageError}
592
+ </CapError>
593
+ )
594
+ }
595
+ value={templateMessage || ''}
596
+ />
597
+ {renderUnsubscribeText()}
598
+ </CapRow>
599
+ {renderMessageLength()}
600
+ </>
601
+ );
602
+ //create methods end
603
+
604
+ //edit methods start
605
+ const getAlertType = () => {
606
+ if (templateStatus === WHATSAPP_STATUSES.approved) {
607
+ return 'success';
608
+ } else if (templateStatus === WHATSAPP_STATUSES.rejected) {
609
+ return 'error';
610
+ }
611
+ return 'warning';
612
+ };
613
+
614
+ const getAlertMessage = () => {
615
+ if (templateStatus === WHATSAPP_STATUSES.approved) {
616
+ return (
617
+ <CapLabel type="label2">
618
+ {formatMessage(messages.approvedStatusMsg)}
619
+ </CapLabel>
620
+ );
621
+ } else if (templateStatus === WHATSAPP_STATUSES.rejected) {
622
+ return (
623
+ <CapLabel type="label2">
624
+ {formatMessage(messages.rejectedStatusMsg)}
625
+ </CapLabel>
626
+ );
627
+ }
628
+ return (
629
+ <>
630
+ <CapLabel type="label2" style={{ fontWeight: 500 }}>
631
+ {formatMessage(messages.awaitingStatusMsg)}
632
+ </CapLabel>
633
+ <CapLabel
634
+ type="label2"
635
+ style={{ marginTop: CAP_SPACE_04, marginBottom: CAP_SPACE_04 }}
636
+ >
637
+ {formatMessage(messages.awaitingStatusDesc, {
638
+ date: moment(templateDate).format('D MMM YYYY'),
639
+ time: moment(templateDate).format('hh:mm A'),
640
+ })}
641
+ </CapLabel>
642
+ </>
643
+ );
644
+ };
645
+
646
+ // on change event of Text Area
647
+ const textAreaValueChange = ({ target: { value, id } }) => {
648
+ const numId = Number(id.slice(id.indexOf('_') + 1));
649
+ const arr = [...updatedSmsEditor];
650
+
651
+ //assign entered value to varMap
652
+ varMap[id] = value;
653
+ //based on entered value update updatedSmsEditor
654
+ if (value === '') {
655
+ arr[numId] = id.slice(0, id.indexOf('_'));
656
+ } else {
657
+ arr[numId] = value;
658
+ }
659
+ setUpdatedSmsEditor(arr);
660
+ };
661
+
662
+ const textAreaValue = (idValue) => {
663
+ if (idValue >= 0 && updatedSmsEditor) {
664
+ const value = updatedSmsEditor[idValue];
665
+ if (value && (value.match(validVarRegex) || []).length === 0) {
666
+ return value;
667
+ }
668
+ return '';
669
+ }
670
+ return '';
671
+ };
672
+
673
+ const renderedEditMessage = () => {
674
+ const renderArray = [];
675
+ if (tempMsgArray?.length !== 0) {
676
+ let varCount = 0;
677
+ tempMsgArray.forEach((elem, index) => {
678
+ if (elem.match(validVarRegex)?.length > 0) {
679
+ varCount += 1;
680
+ renderArray.push(
681
+ <TextArea
682
+ id={`${elem}_${index}`}
683
+ key={`${elem}_${index}`}
684
+ placeholder={formatMessage(messages.inputplaceHolderText, {
685
+ value: `{{${varCount}}}`,
686
+ })}
687
+ autosize={{ minRows: 1, maxRows: 3 }}
688
+ onChange={textAreaValueChange}
689
+ value={textAreaValue(index)}
690
+ onFocus={setTextAreaId}
691
+ disabled={templateStatus !== WHATSAPP_STATUSES.approved}
692
+ />,
693
+ );
694
+ } else {
695
+ renderArray.push(
696
+ <CapHeading
697
+ key={`${elem}_${index}`}
698
+ type="h4"
699
+ className="whatsapp-edit-template-message-heading"
700
+ >
701
+ {elem}
702
+ </CapHeading>,
703
+ );
704
+ }
705
+ });
706
+ }
707
+ renderArray.push(renderUnsubscribeText());
708
+ return renderArray;
709
+ };
710
+
711
+ const editModeContent = (
712
+ <>
713
+ <CapAlert message={getAlertMessage()} type={getAlertType()} />
714
+ <CapRow className="whatsapp-render-heading">
715
+ <CapHeader
716
+ title={
717
+ <CapHeading type="h4">
718
+ {formatMessage(messages.templateMessageLabel)}
719
+ </CapHeading>
720
+ }
721
+ suffix={
722
+ templateStatus === WHATSAPP_STATUSES.approved && (
723
+ <TagList
724
+ label={formatMessage(messages.addLabels)}
725
+ onTagSelect={onTagSelect}
726
+ location={location}
727
+ tags={tags || []}
728
+ onContextChange={handleOnTagsContextChange}
729
+ injectedTags={injectedTags || {}}
730
+ />
731
+ )
732
+ }
733
+ />
734
+ </CapRow>
735
+ <CapTooltip
736
+ title={
737
+ templateStatus === WHATSAPP_STATUSES.approved
738
+ ? ''
739
+ : templateStatus === WHATSAPP_STATUSES.rejected
740
+ ? formatMessage(messages.disabledEditTooltip, {
741
+ status: templateStatus,
742
+ })
743
+ : formatMessage(messages.disabledEditTooltip, {
744
+ status: 'awaiting for approval',
745
+ })
746
+ }
747
+ >
748
+ <CapRow
749
+ className={`whatsapp-edit-template-message-input ${
750
+ templateStatus !== WHATSAPP_STATUSES.approved &&
751
+ 'whatsapp-edit-disabled'
752
+ }`}
753
+ >
754
+ {renderedEditMessage()}
755
+ </CapRow>
756
+ </CapTooltip>
757
+
758
+ {renderMessageLength()}
759
+ </>
760
+ );
761
+ //edit methods end
762
+
763
+ const getPreviewSection = () => {
764
+ const templateMsg = `${
765
+ isEditFlow ? updatedSmsEditor.join('') : templateMessage
766
+ }\n${formatMessage(messages.templateMessageUnsubscribeText)}`;
767
+ return (
768
+ <TemplatePreview
769
+ channel={WHATSAPP}
770
+ content={{ templateMsg }}
771
+ whatsappAccountName={accountName}
772
+ />
773
+ );
774
+ };
775
+
776
+ return (
777
+ <CapSpin spinning={spin}>
778
+ <CapRow>
779
+ <CapColumn span={14}>
780
+ {isEditFlow ? editModeContent : createModeContent}
781
+ <div className="whatsapp-scroll-div" />
782
+ </CapColumn>
783
+ <CapColumn span={6}>
784
+ <CapRow className={isEditFlow ? 'whatsapp-edit-alert-margin' : ''}>
785
+ <CapColumn span={24} offset={9}>
786
+ {getPreviewSection()}
787
+ </CapColumn>
788
+ </CapRow>
789
+ </CapColumn>
790
+ </CapRow>
791
+ <WhatsappFooter>
792
+ {!isEditFlow && (
793
+ <>
794
+ <CapButton
795
+ onClick={onDoneCallback()}
796
+ disabled={isDisableDone()}
797
+ className="whatsapp-create-btn"
798
+ >
799
+ <FormattedMessage {...messages.sendForApprovalButtonLabel} />
800
+ </CapButton>
801
+ <CapButton
802
+ onClick={handleClose}
803
+ className="whatsapp-cancel-btn"
804
+ type="secondary"
805
+ >
806
+ <FormattedMessage {...messages.cancelButtonLabel} />
807
+ </CapButton>
808
+ </>
809
+ )}
810
+ </WhatsappFooter>
811
+ </CapSpin>
812
+ );
813
+ };
814
+
815
+ const mapStateToProps = createStructuredSelector({
816
+ editData: makeSelectWhatsapp(),
817
+ accountData: makeSelectAccount(),
818
+ metaEntities: makeSelectMetaEntities(),
819
+ injectedTags: setInjectedTags(),
820
+ });
821
+
822
+ const mapDispatchToProps = (dispatch) => ({
823
+ actions: bindActionCreators(WhatsappActions, dispatch),
824
+ });
825
+
826
+ export default withCreatives({
827
+ WrappedComponent: injectIntl(Whatsapp),
828
+ mapStateToProps,
829
+ mapDispatchToProps,
830
+ userAuth: true,
831
+ });