@capillarytech/creatives-library 8.0.353-alpha.3 → 8.0.353-alpha.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/package.json +1 -1
  2. package/v2Components/CommonTestAndPreview/UnifiedPreview/PreviewHeader.js +17 -0
  3. package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberPreviewContent.js +14 -132
  4. package/v2Components/CommonTestAndPreview/UnifiedPreview/WebPushPreviewContent.js +169 -0
  5. package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +70 -163
  6. package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +44 -5
  7. package/v2Components/CommonTestAndPreview/constants.js +2 -0
  8. package/v2Components/CommonTestAndPreview/index.js +58 -49
  9. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/PreviewHeader.test.js +159 -0
  10. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ViberPreviewContent.test.js +0 -364
  11. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/WebPushPreviewContent.test.js +522 -0
  12. package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +255 -0
  13. package/v2Components/CommonTestAndPreview/tests/constants.test.js +2 -1
  14. package/v2Components/CommonTestAndPreview/tests/index.test.js +194 -0
  15. package/v2Components/TestAndPreviewSlidebox/index.js +2 -2
  16. package/v2Containers/App/constants.js +3 -0
  17. package/v2Containers/App/tests/constants.test.js +61 -0
  18. package/v2Containers/Templates/_templates.scss +0 -77
  19. package/v2Containers/Templates/index.js +70 -77
  20. package/v2Containers/Templates/tests/webpush.test.js +375 -0
  21. package/v2Containers/Viber/constants.js +0 -19
  22. package/v2Containers/Viber/index.js +47 -714
  23. package/v2Containers/Viber/index.scss +0 -148
  24. package/v2Containers/Viber/messages.js +0 -116
  25. package/v2Containers/Viber/tests/index.test.js +0 -80
  26. package/v2Containers/WebPush/Create/index.js +91 -8
  27. package/v2Containers/WebPush/Create/index.scss +7 -0
  28. package/v2Containers/WebPush/Create/tests/getTemplateContent.test.js +338 -0
  29. package/v2Containers/WebPush/Create/tests/testAndPreviewIntegration.test.js +325 -0
@@ -2116,8 +2116,6 @@
2116
2116
  flex: 1;
2117
2117
  display: flex;
2118
2118
  flex-direction: column;
2119
- overflow-y: auto;
2120
- -webkit-overflow-scrolling: touch;
2121
2119
  padding: 0 $CAP_SPACE_16;
2122
2120
  background-color: #ffffff;
2123
2121
  margin-left: $CAP_SPACE_06;
@@ -2143,12 +2141,6 @@
2143
2141
  margin-top: $CAP_SPACE_16;
2144
2142
  width: 68%;
2145
2143
 
2146
- &.viber-preview-carousel {
2147
- width: 100%;
2148
- margin-left: $CAP_SPACE_12;
2149
- max-height: none;
2150
- }
2151
-
2152
2144
  // Account icon (from TemplatePreview line 1146-1160)
2153
2145
  .viber-account-icon {
2154
2146
  width: $CAP_SPACE_20;
@@ -2177,18 +2169,6 @@
2177
2169
  border-radius: $CAP_SPACE_04;
2178
2170
  padding: $CAP_SPACE_04;
2179
2171
 
2180
- &.viber-message-pop-carousel {
2181
- width: 100%;
2182
- left: 0;
2183
- margin-top: 0;
2184
- padding: 0;
2185
- background: transparent;
2186
- display: flex;
2187
- flex-direction: column;
2188
- align-items: flex-start;
2189
- gap: $CAP_SPACE_06;
2190
- }
2191
-
2192
2172
  // Text Viber preview (from TemplatePreview line 1166-1174)
2193
2173
  .viber-message-text {
2194
2174
  margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
@@ -2260,149 +2240,6 @@
2260
2240
  }
2261
2241
  }
2262
2242
 
2263
- .viber-carousel-message-pop,
2264
- .viber-carousel-cards-pop {
2265
- width: 100%;
2266
- background: $CAP_G08;
2267
- border-radius: $CAP_SPACE_06;
2268
- padding: $CAP_SPACE_08;
2269
- }
2270
-
2271
- .viber-carousel-message-pop {
2272
- margin-top: 0;
2273
- width: 68%;
2274
- border-radius: 0 $CAP_SPACE_06 $CAP_SPACE_06 $CAP_SPACE_06;
2275
- }
2276
-
2277
- .viber-carousel-cards-pop {
2278
- margin-top: 0;
2279
- width: 100%;
2280
- background: transparent;
2281
- border: none;
2282
- border-radius: 0;
2283
- padding: 0;
2284
- }
2285
-
2286
- .viber-carousel-message-box {
2287
- width: 100%;
2288
- min-height: 2.25rem;
2289
- height: auto;
2290
- border-radius: $CAP_SPACE_04;
2291
- background: transparent;
2292
- padding: 0 $CAP_SPACE_08;
2293
- display: flex;
2294
- align-items: center;
2295
- }
2296
-
2297
- .viber-carousel-message-box-text {
2298
- color: $CAP_G01;
2299
- margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
2300
- white-space: normal;
2301
- word-break: break-word;
2302
- overflow: visible;
2303
- width: 100%;
2304
- }
2305
-
2306
- .viber-carousel-message-box-placeholder {
2307
- width: 100%;
2308
- height: 0.875rem;
2309
- border-radius: $CAP_SPACE_04;
2310
- background: $CAP_G07;
2311
- }
2312
-
2313
- .viber-carousel-message-timestamp,
2314
- .viber-carousel-cards-timestamp {
2315
- display: block;
2316
- text-align: right;
2317
- margin-top: $CAP_SPACE_06;
2318
- color: $CAP_G04;
2319
- }
2320
-
2321
- .viber-carousel-preview-scroll {
2322
- display: flex;
2323
- width: 100%;
2324
- overflow-x: auto;
2325
- overflow-y: visible;
2326
-
2327
- scrollbar-width: none;
2328
- -webkit-overflow-scrolling: touch;
2329
-
2330
- &::-webkit-scrollbar {
2331
- display: none;
2332
- }
2333
-
2334
- .viber-carousel-preview-card {
2335
- flex: 0 0 68%;
2336
- min-width: 68%;
2337
- margin-right: $CAP_SPACE_08;
2338
- background: $CAP_G09;
2339
- border: 1px solid $CAP_G07;
2340
- border-radius: $CAP_SPACE_12;
2341
- overflow: hidden;
2342
- display: flex;
2343
- flex-direction: column;
2344
-
2345
- &:last-child {
2346
- margin-right: 0;
2347
- }
2348
-
2349
- .viber-carousel-preview-card-body {
2350
- padding: $CAP_SPACE_08;
2351
- display: flex;
2352
- flex-direction: column;
2353
- gap: $CAP_SPACE_06;
2354
- }
2355
-
2356
- .viber-carousel-preview-image {
2357
- width: 100%;
2358
- height: 10rem;
2359
- object-fit: cover;
2360
- border-radius: 0;
2361
- }
2362
-
2363
- .viber-carousel-preview-image-placeholder {
2364
- width: 100%;
2365
- height: 10rem;
2366
- border-radius: 0;
2367
- background: $CAP_G07;
2368
- }
2369
-
2370
- .viber-carousel-preview-text {
2371
- color: $CAP_G01;
2372
- line-height: 1.3;
2373
- white-space: normal;
2374
- }
2375
-
2376
- .viber-carousel-preview-text-placeholder {
2377
- width: 100%;
2378
- height: 0.875rem;
2379
- border-radius: $CAP_SPACE_04;
2380
- background: $CAP_G07;
2381
- min-height: 0.875rem;
2382
- }
2383
-
2384
- .viber-carousel-preview-button {
2385
- color: $CAP_WHITE;
2386
- background: $CAP_PURPLE01;
2387
- border-radius: $CAP_SPACE_12;
2388
- text-align: center;
2389
- width: 100%;
2390
- display: flex;
2391
- align-items: center;
2392
- justify-content: center;
2393
- min-height: 1.5rem;
2394
- padding: $CAP_SPACE_06 $CAP_SPACE_08;
2395
- white-space: normal;
2396
- }
2397
-
2398
- .viber-carousel-preview-button-secondary {
2399
- color: $CAP_PURPLE01;
2400
- background: transparent;
2401
- border: none;
2402
- }
2403
- }
2404
- }
2405
-
2406
2243
  .empty-placeholder {
2407
2244
  height: $CAP_SPACE_08;
2408
2245
  }
@@ -2513,6 +2350,76 @@
2513
2350
  }
2514
2351
  }
2515
2352
 
2353
+ // WebPush Test & Preview Styles
2354
+ .webpush-test-preview-container {
2355
+ width: 100%;
2356
+ position: relative;
2357
+ padding-left: $CAP_SPACE_16;
2358
+ padding-right: $CAP_SPACE_16;
2359
+ }
2360
+
2361
+ .webpush-preview-panel {
2362
+ position: relative;
2363
+ width: 100%;
2364
+ }
2365
+
2366
+ .webpush-expand-btn {
2367
+ position: absolute;
2368
+ top: 8px;
2369
+ right: 8px;
2370
+ z-index: 10;
2371
+ padding: 4px;
2372
+ display: flex;
2373
+ align-items: center;
2374
+ justify-content: center;
2375
+
2376
+ &:hover {
2377
+ background-color: rgba(0, 0, 0, 0.06);
2378
+ border-radius: 4px;
2379
+ }
2380
+ }
2381
+
2382
+ .webpush-fullscreen-modal {
2383
+ .webpush-fullscreen-divider {
2384
+ margin-top: 0;
2385
+ margin-bottom: $CAP_SPACE_16;
2386
+ }
2387
+ .ant-modal.cap-modal-v2 {
2388
+ width: 90%;
2389
+ max-width: 100%;
2390
+ margin-top: $CAP_SPACE_40;
2391
+ }
2392
+ // Preview Chrome wrapper (matches old TestAndPreviewSlidebox design)
2393
+ .webpush-preview-header {
2394
+ background: $CAP_WHITE;
2395
+ overflow: hidden;
2396
+
2397
+ .preview-divider {
2398
+ margin: 0;
2399
+ }
2400
+
2401
+ .webpush-heading-container {
2402
+ display: flex;
2403
+ justify-content: space-between;
2404
+ align-items: center;
2405
+ padding: $CAP_SPACE_16 0 $CAP_SPACE_16 0;
2406
+
2407
+ .preview-for {
2408
+ gap: $CAP_SPACE_04;
2409
+ align-items: center;
2410
+ b {
2411
+ margin-left: $CAP_SPACE_08;
2412
+ }
2413
+ }
2414
+
2415
+ .webpush-fullscreen-close-icon {
2416
+ width: $CAP_SPACE_24;
2417
+ height: $CAP_SPACE_24;
2418
+ }
2419
+ }
2420
+ }
2421
+ }
2422
+
2516
2423
  // Responsive adjustments
2517
2424
  @media (max-width: 85.714rem) {
2518
2425
  .unified-preview {
@@ -6,7 +6,7 @@
6
6
  * Routes to channel-specific preview content components
7
7
  */
8
8
 
9
- import React from 'react';
9
+ import React, { useState } from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  import CapRow from '@capillarytech/cap-ui-library/CapRow';
12
12
  import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
@@ -21,6 +21,7 @@ import InAppPreviewContent from './InAppPreviewContent';
21
21
  import MobilePushPreviewContent from './MobilePushPreviewContent';
22
22
  import ViberPreviewContent from './ViberPreviewContent';
23
23
  import ZaloPreviewContent from './ZaloPreviewContent';
24
+ import WebPushPreviewContent from './WebPushPreviewContent';
24
25
  import { CHANNELS, DESKTOP, TABLET, MOBILE, ANDROID, IOS } from '../constants';
25
26
  import messages from '../messages';
26
27
  import './_unifiedPreview.scss';
@@ -44,6 +45,7 @@ const UnifiedPreview = ({
44
45
  * For Phase 5, we'll render placeholders
45
46
  * Phase 6+ will implement actual content components
46
47
  */
48
+ const [isFullscreenOpen, setIsFullscreenOpen] = useState(false);
47
49
  const renderChannelContent = () => {
48
50
  // Phase 5: Placeholder content for all channels
49
51
  // Phase 6+: Import and render actual channel-specific components
@@ -197,6 +199,40 @@ const UnifiedPreview = ({
197
199
  );
198
200
  }
199
201
 
202
+ case CHANNELS.WEBPUSH: {
203
+ // WebPush content arrives as a JSON string (from getCurrentContent or preview API response)
204
+ let webPushOuter = {};
205
+ try {
206
+ webPushOuter = typeof content === 'string' ? JSON.parse(content) : (typeof content === 'object' && content !== null ? content : {});
207
+ } catch (e) {
208
+ webPushOuter = {};
209
+ }
210
+ const webPushInner = webPushOuter?.content || {};
211
+ const webPushExpandable = webPushInner?.expandableDetails || {};
212
+ const webPushMedia = webPushExpandable?.media || [];
213
+ const webPushCtas = webPushExpandable?.ctas || [];
214
+ const webPushButtons = webPushCtas.map((cta) => ({
215
+ text: cta?.title || '',
216
+ url: cta?.actionLink || '',
217
+ type: cta?.type || '',
218
+ }));
219
+ return (
220
+ <WebPushPreviewContent
221
+ notificationTitle={webPushInner?.title || ''}
222
+ notificationBody={webPushInner?.message || ''}
223
+ imageSrc={webPushMedia[0]?.url || ''}
224
+ brandIconSrc={webPushInner?.iconImageUrl || ''}
225
+ buttons={webPushButtons}
226
+ url={webPushInner?.cta?.actionLink || ''}
227
+ isUpdating={isUpdating}
228
+ error={error}
229
+ isFullscreenOpen={isFullscreenOpen}
230
+ setIsFullscreenOpen={setIsFullscreenOpen}
231
+ selectedCustomer={selectedCustomer}
232
+ />
233
+ );
234
+ }
235
+
200
236
  default:
201
237
  return (
202
238
  <div className="channel-preview-placeholder">
@@ -222,9 +258,10 @@ const UnifiedPreview = ({
222
258
  <PreviewHeader
223
259
  selectedCustomer={selectedCustomer}
224
260
  device={device}
225
- showDeviceToggle={showDeviceToggle}
261
+ showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
226
262
  onDeviceChange={onDeviceChange}
227
263
  channel={channel}
264
+ setIsFullscreenOpen={setIsFullscreenOpen}
228
265
  />
229
266
  )}
230
267
  <CapRow className="preview-loading-container">
@@ -247,9 +284,10 @@ const UnifiedPreview = ({
247
284
  <PreviewHeader
248
285
  selectedCustomer={selectedCustomer}
249
286
  device={device}
250
- showDeviceToggle={showDeviceToggle}
287
+ showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
251
288
  onDeviceChange={onDeviceChange}
252
289
  channel={channel}
290
+ setIsFullscreenOpen={setIsFullscreenOpen}
253
291
  />
254
292
  )}
255
293
  <CapRow className="preview-error-container">
@@ -275,15 +313,16 @@ const UnifiedPreview = ({
275
313
  <PreviewHeader
276
314
  selectedCustomer={selectedCustomer}
277
315
  device={device}
278
- showDeviceToggle={showDeviceToggle}
316
+ showDeviceToggle={channel !== CHANNELS.WEBPUSH && showDeviceToggle}
279
317
  onDeviceChange={onDeviceChange}
280
318
  channel={channel}
319
+ setIsFullscreenOpen={setIsFullscreenOpen}
281
320
  />
282
321
  )}
283
322
 
284
323
  {/* Channel-specific preview content */}
285
324
  <CapRow className={`preview-content-container ${!showHeader ? 'preview-content-container-no-header' : ''}`}>
286
- {[CHANNELS.EMAIL, CHANNELS.SMS, CHANNELS.WHATSAPP, CHANNELS.RCS, CHANNELS.INAPP, CHANNELS.MOBILEPUSH, CHANNELS.VIBER].includes(channel) ? (
325
+ {[CHANNELS.EMAIL, CHANNELS.SMS, CHANNELS.WHATSAPP, CHANNELS.RCS, CHANNELS.INAPP, CHANNELS.MOBILEPUSH, CHANNELS.VIBER, CHANNELS.WEBPUSH].includes(channel) ? (
287
326
  renderChannelContent()
288
327
  ) : (
289
328
  <DeviceFrame device={device || DESKTOP}>
@@ -85,6 +85,7 @@ export const CHANNELS = {
85
85
  MOBILEPUSH: 'MOBILEPUSH',
86
86
  VIBER: 'VIBER',
87
87
  ZALO: 'ZALO',
88
+ WEBPUSH: 'WEBPUSH',
88
89
  };
89
90
  export const CHANNELS_USING_ANDROID_PREVIEW_DEVICE = [CHANNELS.SMS, CHANNELS.RCS, CHANNELS.WHATSAPP, CHANNELS.VIBER, CHANNELS.ZALO, CHANNELS.INAPP, CHANNELS.MOBILEPUSH];
90
91
 
@@ -203,6 +204,7 @@ export const DYNAMIC_URL = 'DYNAMIC_URL';
203
204
  export const IMAGE = 'IMAGE';
204
205
  export const VIDEO = 'VIDEO';
205
206
  export const URL = 'URL';
207
+ export const DAYS = 'DAYS';
206
208
 
207
209
  // Initial Payload Template (for reference)
208
210
  export const INITIAL_PAYLOAD = {
@@ -81,7 +81,8 @@ import {
81
81
  IMAGE,
82
82
  VIDEO,
83
83
  URL,
84
- CHANNELS_USING_ANDROID_PREVIEW_DEVICE
84
+ CHANNELS_USING_ANDROID_PREVIEW_DEVICE,
85
+ DAYS,
85
86
  } from './constants';
86
87
 
87
88
  // Import utilities
@@ -610,6 +611,12 @@ const CommonTestAndPreview = (props) => {
610
611
  messageBody: contentStr,
611
612
  };
612
613
 
614
+ case CHANNELS.WEBPUSH:
615
+ return {
616
+ ...basePayload,
617
+ messageBody: contentStr,
618
+ };
619
+
613
620
  default:
614
621
  return basePayload;
615
622
  }
@@ -662,6 +669,12 @@ const CommonTestAndPreview = (props) => {
662
669
  templateContent: contentStr,
663
670
  };
664
671
 
672
+ case CHANNELS.WEBPUSH:
673
+ return {
674
+ templateSubject: formDataObj?.content?.title || '',
675
+ templateContent: contentStr,
676
+ };
677
+
665
678
  case CHANNELS.ZALO: {
666
679
  // For Zalo, extract content from templateListParams array
667
680
  // Combine all variable values into a single string for tag extraction
@@ -1554,8 +1567,6 @@ const CommonTestAndPreview = (props) => {
1554
1567
  let imageData = null;
1555
1568
  let videoData = null;
1556
1569
  let buttonData = null;
1557
- let cardsData = [];
1558
- let messageType = '';
1559
1570
  let accountId = null;
1560
1571
  let accountDetails = null;
1561
1572
  let scenarioKey = '';
@@ -1570,8 +1581,6 @@ const CommonTestAndPreview = (props) => {
1570
1581
  imageData = formDataObj.image || null;
1571
1582
  videoData = formDataObj.video || null;
1572
1583
  buttonData = formDataObj.button || null;
1573
- cardsData = formDataObj.cards || [];
1574
- messageType = formDataObj.type || '';
1575
1584
  accountId = formDataObj.accountId || null;
1576
1585
  accountDetails = formDataObj.accountDetails || null;
1577
1586
  scenarioKey = formDataObj.scenarioKey || VIBER_API_SCENARIO_KEY;
@@ -1598,8 +1607,6 @@ const CommonTestAndPreview = (props) => {
1598
1607
  url: formDataObj?.buttonURL || '',
1599
1608
  };
1600
1609
  }
1601
- cardsData = viberPreview.cards || formDataObj?.cards || [];
1602
- messageType = viberPreview.type || formDataObj?.type || '';
1603
1610
  // Extract account info from parent formDataObj if available
1604
1611
  accountId = formDataObj.accountId || null;
1605
1612
  accountDetails = formDataObj.accountDetails || null;
@@ -1642,10 +1649,6 @@ const CommonTestAndPreview = (props) => {
1642
1649
  text: messageText,
1643
1650
  };
1644
1651
 
1645
- if (messageType === CHANNELS.VIBER) {
1646
- messageType = '';
1647
- }
1648
-
1649
1652
  // Add image if present
1650
1653
  if (imageData && imageData.url) {
1651
1654
  viberContent.image = {
@@ -1674,19 +1677,6 @@ const CommonTestAndPreview = (props) => {
1674
1677
  }
1675
1678
  }
1676
1679
 
1677
- if (messageType === MEDIA_TYPE_CAROUSEL || (Array.isArray(cardsData) && cardsData.length)) {
1678
- viberContent.type = MEDIA_TYPE_CAROUSEL;
1679
- viberContent.cards = (cardsData || []).map((card) => ({
1680
- text: card?.text || '',
1681
- mediaUrl: card?.mediaUrl || '',
1682
- buttons: (card?.buttons || []).map((button) => ({
1683
- title: button?.title || '',
1684
- action: button?.action || '',
1685
- })),
1686
- }));
1687
- delete viberContent.button;
1688
- }
1689
-
1690
1680
  // Resolve tags in text if custom values are provided
1691
1681
  if (customValuesObj && Object.keys(customValuesObj).length > 0 && viberContent.text) {
1692
1682
  viberContent.text = resolveTagsInText(viberContent.text, customValuesObj);
@@ -1824,6 +1814,42 @@ const CommonTestAndPreview = (props) => {
1824
1814
  };
1825
1815
  }
1826
1816
 
1817
+ case CHANNELS.WEBPUSH: {
1818
+ const webpushData = (typeof formDataObj === 'object' && formDataObj !== null)
1819
+ ? formDataObj
1820
+ : {};
1821
+ const innerContent = webpushData?.content || {};
1822
+
1823
+ const resolvedTitle = resolveTagsInText(innerContent?.title || '', customValuesObj);
1824
+ const resolvedMessage = resolveTagsInText(innerContent?.message || '', customValuesObj);
1825
+
1826
+ return {
1827
+ ...basePayload,
1828
+ webPushMessageContent: {
1829
+ channel: CHANNELS.WEBPUSH,
1830
+ accountId: webpushData?.accountId || null,
1831
+ content: {
1832
+ title: resolvedTitle,
1833
+ message: resolvedMessage,
1834
+ ...(innerContent?.iconImageUrl && { iconImageUrl: innerContent.iconImageUrl }),
1835
+ ...(innerContent?.cta && { cta: innerContent.cta }),
1836
+ ...(innerContent?.expandableDetails && { expandableDetails: innerContent.expandableDetails }),
1837
+ },
1838
+ messageSubject: webpushData?.messageSubject || resolvedTitle || '',
1839
+ },
1840
+ webPushDeliverySettings: {
1841
+ channelSettings: {
1842
+ channel: CHANNELS.WEBPUSH,
1843
+ notificationTtl: {
1844
+ duration: 7,
1845
+ timeUnit: DAYS,
1846
+ },
1847
+ },
1848
+ additionalSettings: {},
1849
+ },
1850
+ };
1851
+ }
1852
+
1827
1853
  default:
1828
1854
  return basePayload;
1829
1855
  }
@@ -1855,7 +1881,7 @@ const CommonTestAndPreview = (props) => {
1855
1881
  contentObj = hasPreviewCallBeenMade && previewDataHtml?.resolvedBody
1856
1882
  ? previewDataHtml.resolvedBody
1857
1883
  : getCurrentContent || '';
1858
- } else if (channel === CHANNELS.WHATSAPP) {
1884
+ } else if (channel === CHANNELS.WHATSAPP || channel === CHANNELS.WEBPUSH) {
1859
1885
  // For WhatsApp, content is an object with templateMsg, media, CTA, etc.
1860
1886
  // Content comes from WhatsApp component state, passed via content prop
1861
1887
  let resolvedContent = null;
@@ -2033,13 +2059,6 @@ const CommonTestAndPreview = (props) => {
2033
2059
  // Only use previewDataHtml if preview call was made
2034
2060
  if (hasPreviewCallBeenMade && previewDataHtml?.resolvedBody) {
2035
2061
  resolvedContent = previewDataHtml.resolvedBody;
2036
- if (typeof resolvedContent === 'string') {
2037
- try {
2038
- resolvedContent = JSON.parse(resolvedContent);
2039
- } catch (e) {
2040
- resolvedContent = null;
2041
- }
2042
- }
2043
2062
  }
2044
2063
 
2045
2064
  // Parse content if it's a string
@@ -2051,25 +2070,15 @@ const CommonTestAndPreview = (props) => {
2051
2070
  parsedViberContent = {};
2052
2071
  }
2053
2072
  }
2054
- // Merge template preview state with API resolved body so carousel type/cards survive slim responses
2073
+ // Use resolvedContent if available (from preview call), otherwise use raw content
2055
2074
  if (resolvedContent && typeof resolvedContent === 'object') {
2056
- const base = parsedViberContent && typeof parsedViberContent === 'object' ? parsedViberContent : {};
2057
- contentObj = {
2058
- ...base,
2059
- ...resolvedContent,
2060
- viberPreviewContent: {
2061
- ...base.viberPreviewContent,
2062
- ...resolvedContent.viberPreviewContent,
2063
- ...(resolvedContent.messageContent != null && typeof resolvedContent.messageContent === 'string'
2064
- ? { messageContent: resolvedContent.messageContent }
2065
- : {}),
2066
- },
2067
- };
2068
- if (base.accountName && !contentObj.accountName) {
2069
- contentObj.accountName = base.accountName;
2075
+ contentObj = { ...resolvedContent };
2076
+ // Merge in accountName and brandName from raw content if not in resolvedContent
2077
+ if (parsedViberContent?.accountName && !contentObj.accountName) {
2078
+ contentObj.accountName = parsedViberContent.accountName;
2070
2079
  }
2071
- if (base.brandName && !contentObj.brandName) {
2072
- contentObj.brandName = base.brandName;
2080
+ if (parsedViberContent?.brandName && !contentObj.brandName) {
2081
+ contentObj.brandName = parsedViberContent.brandName;
2073
2082
  }
2074
2083
  } else {
2075
2084
  // Use raw content if no preview call was made or resolvedContent is not available