tee3apps-cms-sdk-react 0.0.15 → 0.0.16

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tee3apps-cms-sdk-react",
3
- "version": "0.0.15",
3
+ "version": "0.0.16",
4
4
  "description": "Uses JSON to dynamically generate and render UI pages in a website",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -3,6 +3,83 @@ import ProductListViewOne from '../Visual-Components/Styles/ProductListViewOne';
3
3
  import ProductListViewTwo from '../Visual-Components/Styles/ProductListViewTwo';
4
4
  import { Linodeurl } from '../../const';
5
5
 
6
+ // Utility function to extract price value from different formats
7
+ const getPriceValue = (price: any): number => {
8
+ if (price === null || price === undefined) return 0;
9
+
10
+ // If it's already a number
11
+ if (typeof price === 'number') {
12
+ return isNaN(price) ? 0 : price;
13
+ }
14
+
15
+ // If it's an object with $numberDecimal (but not an array)
16
+ if (typeof price === 'object' && price !== null && !Array.isArray(price)) {
17
+ if (price.$numberDecimal !== undefined && price.$numberDecimal !== null) {
18
+ const value = parseFloat(String(price.$numberDecimal));
19
+ return isNaN(value) ? 0 : value;
20
+ }
21
+ }
22
+
23
+ // If it's a string, try to parse it
24
+ if (typeof price === 'string') {
25
+ const value = parseFloat(price);
26
+ return isNaN(value) ? 0 : value;
27
+ }
28
+
29
+ return 0;
30
+ };
31
+
32
+ // Utility function to get price from pricing array (mrp, costPrice, nlcPrice)
33
+ const getPriceFromPricingArray = (pricingArray: any[]): number => {
34
+ if (!Array.isArray(pricingArray) || pricingArray.length === 0) return 0;
35
+
36
+ // First, try to find the default price with default currency
37
+ const defaultPrice = pricingArray.find(
38
+ (item: any) => item.isDefault === true && item.isDefaultCurrency === true
39
+ );
40
+
41
+ if (defaultPrice && defaultPrice.price) {
42
+ return getPriceValue(defaultPrice.price);
43
+ }
44
+
45
+ // Fallback: find any default price
46
+ const anyDefault = pricingArray.find((item: any) => item.isDefault === true);
47
+ if (anyDefault && anyDefault.price) {
48
+ return getPriceValue(anyDefault.price);
49
+ }
50
+
51
+ // Fallback: use first item
52
+ if (pricingArray[0] && pricingArray[0].price) {
53
+ return getPriceValue(pricingArray[0].price);
54
+ }
55
+
56
+ return 0;
57
+ };
58
+
59
+ // Utility function to get MRP and Selling Price from product pricing object
60
+ const getProductPrices = (product: any) => {
61
+ // Use pricing object first, fallback to price for backward compatibility
62
+ const mrp = product.pricing?.mrp ? getPriceFromPricingArray(product.pricing.mrp) : 0;
63
+ const sellingPrice = product.pricing?.nlcPrice
64
+ ? getPriceFromPricingArray(product.pricing.nlcPrice)
65
+ : product.pricing?.costPrice
66
+ ? getPriceFromPricingArray(product.pricing.costPrice)
67
+ : 0;
68
+
69
+ // Fallback to old price structure if pricing is not available
70
+ const fallbackMRP = product.price?.MRP
71
+ ? getPriceValue(product.price.MRP)
72
+ : 0;
73
+ const fallbackSP = product.price?.SP
74
+ ? getPriceValue(product.price.SP)
75
+ : 0;
76
+
77
+ return {
78
+ mrp: mrp || fallbackMRP,
79
+ sellingPrice: sellingPrice || fallbackSP
80
+ };
81
+ };
82
+
6
83
 
7
84
  interface Product {
8
85
  _id: string;
@@ -127,7 +204,7 @@ const GroupProductComponent: React.FC<GroupProductComponentMainProps> = ({
127
204
  };
128
205
 
129
206
  const products = getProducts();
130
-
207
+
131
208
  // Helper function to render product based on style
132
209
  const renderProduct = (product: Product, key: string) => {
133
210
  if (currentstyle === 'STYLE1') {
@@ -207,9 +284,14 @@ const GroupProductComponent: React.FC<GroupProductComponentMainProps> = ({
207
284
  }}
208
285
  >
209
286
  {typeof product.name === 'object' ? product.name.all : product.name}
210
- <h1 style={{ fontSize: '16px', fontWeight: '700', color: '#333' }}>
211
- {product?.price?.SP?.$numberDecimal}
212
- </h1>
287
+ {(() => {
288
+ const prices = getProductPrices(product);
289
+ return prices.sellingPrice > 0 ? (
290
+ <h1 style={{ fontSize: '16px', fontWeight: '700', color: '#333' }}>
291
+ ₹{prices.sellingPrice.toLocaleString("en-IN")}
292
+ </h1>
293
+ ) : null;
294
+ })()}
213
295
  </div>
214
296
  )}
215
297
  </div>
@@ -2,6 +2,59 @@ import React from "react";
2
2
  import "./product-list-view-one.css";
3
3
  import { Linodeurl } from '../../../const';
4
4
 
5
+ // Utility function to extract price value from different formats
6
+ const getPriceValue = (price: any): number => {
7
+ if (price === null || price === undefined) return 0;
8
+
9
+ // If it's already a number
10
+ if (typeof price === 'number') {
11
+ return isNaN(price) ? 0 : price;
12
+ }
13
+
14
+ // If it's an object with $numberDecimal (but not an array)
15
+ if (typeof price === 'object' && price !== null && !Array.isArray(price)) {
16
+ if (price.$numberDecimal !== undefined && price.$numberDecimal !== null) {
17
+ const value = parseFloat(String(price.$numberDecimal));
18
+ return isNaN(value) ? 0 : value;
19
+ }
20
+ }
21
+
22
+ // If it's a string, try to parse it
23
+ if (typeof price === 'string') {
24
+ const value = parseFloat(price);
25
+ return isNaN(value) ? 0 : value;
26
+ }
27
+
28
+ return 0;
29
+ };
30
+
31
+ // Utility function to get price from pricing array (mrp, costPrice, nlcPrice)
32
+ const getPriceFromPricingArray = (pricingArray: any[]): number => {
33
+ if (!Array.isArray(pricingArray) || pricingArray.length === 0) return 0;
34
+
35
+ // First, try to find the default price with default currency
36
+ const defaultPrice = pricingArray.find(
37
+ (item: any) => item.isDefault === true && item.isDefaultCurrency === true
38
+ );
39
+
40
+ if (defaultPrice && defaultPrice.price) {
41
+ return getPriceValue(defaultPrice.price);
42
+ }
43
+
44
+ // Fallback: find any default price
45
+ const anyDefault = pricingArray.find((item: any) => item.isDefault === true);
46
+ if (anyDefault && anyDefault.price) {
47
+ return getPriceValue(anyDefault.price);
48
+ }
49
+
50
+ // Fallback: use first item
51
+ if (pricingArray[0] && pricingArray[0].price) {
52
+ return getPriceValue(pricingArray[0].price);
53
+ }
54
+
55
+ return 0;
56
+ };
57
+
5
58
  const ProductListViewOne = (props: any) => {
6
59
  const [target, setTarget] = React.useState("_blank");
7
60
  console.warn(props)
@@ -23,13 +76,21 @@ const ProductListViewOne = (props: any) => {
23
76
  const data = props.props || props;
24
77
  const slug = data?.code; // Using code instead of slug
25
78
 
26
- // Updated price extraction to match your JSON structure
27
- const sellingPrice = Number(data?.price?.SP?.$numberDecimal || 0);
28
- const mrpPrice = Number(data?.price?.MRP?.$numberDecimal || 0);
79
+ // Updated price extraction to use pricing object
80
+ const mrp = data.pricing?.mrp ? getPriceFromPricingArray(data.pricing.mrp) : 0;
81
+ const sellingPrice = data.pricing?.nlcPrice
82
+ ? getPriceFromPricingArray(data.pricing.nlcPrice)
83
+ : data.pricing?.costPrice
84
+ ? getPriceFromPricingArray(data.pricing.costPrice)
85
+ : 0;
86
+
87
+ // Fallback to old price structure if pricing is not available
88
+ const mrpPrice = mrp || (data.price?.MRP ? getPriceValue(data.price.MRP) : 0);
89
+ const finalSellingPrice = sellingPrice || (data.price?.SP ? getPriceValue(data.price.SP) : 0);
29
90
 
30
91
  const calculateDiscount = (): number | null => {
31
- if (!sellingPrice || !mrpPrice || mrpPrice <= sellingPrice) return null;
32
- return Math.round(100 - (sellingPrice / mrpPrice) * 100);
92
+ if (!finalSellingPrice || !mrpPrice || mrpPrice <= finalSellingPrice) return null;
93
+ return Math.round(100 - (finalSellingPrice / mrpPrice) * 100);
33
94
  };
34
95
 
35
96
  const discount = calculateDiscount();
@@ -62,11 +123,11 @@ const ProductListViewOne = (props: any) => {
62
123
  <h5>{variantOptions}</h5>
63
124
  </div>
64
125
  <div className="card_value">
65
- {sellingPrice !== 0 && (
126
+ {finalSellingPrice !== 0 && (
66
127
  <div className="card_price">
67
- <h4>₹{sellingPrice.toLocaleString("en-IN")}</h4>
128
+ <h4>₹{finalSellingPrice.toLocaleString("en-IN")}</h4>
68
129
  <div className="card_right_grid">
69
- {mrpPrice > sellingPrice && (
130
+ {mrpPrice > finalSellingPrice && (
70
131
  <p >₹{mrpPrice.toLocaleString("en-IN")}</p>
71
132
  )}
72
133
  {discount !== null && discount > 0 && (
@@ -2,6 +2,59 @@ import React from "react";
2
2
  import "./product-list-view-two.css";
3
3
  import { Linodeurl } from '../../../const';
4
4
 
5
+ // Utility function to extract price value from different formats
6
+ const getPriceValue = (price: any): number => {
7
+ if (price === null || price === undefined) return 0;
8
+
9
+ // If it's already a number
10
+ if (typeof price === 'number') {
11
+ return isNaN(price) ? 0 : price;
12
+ }
13
+
14
+ // If it's an object with $numberDecimal (but not an array)
15
+ if (typeof price === 'object' && price !== null && !Array.isArray(price)) {
16
+ if (price.$numberDecimal !== undefined && price.$numberDecimal !== null) {
17
+ const value = parseFloat(String(price.$numberDecimal));
18
+ return isNaN(value) ? 0 : value;
19
+ }
20
+ }
21
+
22
+ // If it's a string, try to parse it
23
+ if (typeof price === 'string') {
24
+ const value = parseFloat(price);
25
+ return isNaN(value) ? 0 : value;
26
+ }
27
+
28
+ return 0;
29
+ };
30
+
31
+ // Utility function to get price from pricing array (mrp, costPrice, nlcPrice)
32
+ const getPriceFromPricingArray = (pricingArray: any[]): number => {
33
+ if (!Array.isArray(pricingArray) || pricingArray.length === 0) return 0;
34
+
35
+ // First, try to find the default price with default currency
36
+ const defaultPrice = pricingArray.find(
37
+ (item: any) => item.isDefault === true && item.isDefaultCurrency === true
38
+ );
39
+
40
+ if (defaultPrice && defaultPrice.price) {
41
+ return getPriceValue(defaultPrice.price);
42
+ }
43
+
44
+ // Fallback: find any default price
45
+ const anyDefault = pricingArray.find((item: any) => item.isDefault === true);
46
+ if (anyDefault && anyDefault.price) {
47
+ return getPriceValue(anyDefault.price);
48
+ }
49
+
50
+ // Fallback: use first item
51
+ if (pricingArray[0] && pricingArray[0].price) {
52
+ return getPriceValue(pricingArray[0].price);
53
+ }
54
+
55
+ return 0;
56
+ };
57
+
5
58
  const ProductListViewTwo = (props: any) => {
6
59
  console.warn(props);
7
60
  const [target, setTarget] = React.useState("_blank");
@@ -24,13 +77,21 @@ const ProductListViewTwo = (props: any) => {
24
77
  const data = props.props || props;
25
78
  const slug = data?.code; // Using code instead of slug since slug doesn't exist in your data
26
79
 
27
- // Updated price extraction to match your JSON structure
28
- const sellingPrice = Number(data?.price?.SP?.$numberDecimal || 0);
29
- const mrpPrice = Number(data?.price?.MRP?.$numberDecimal || 0);
80
+ // Updated price extraction to use pricing object
81
+ const mrp = data.pricing?.mrp ? getPriceFromPricingArray(data.pricing.mrp) : 0;
82
+ const sellingPrice = data.pricing?.nlcPrice
83
+ ? getPriceFromPricingArray(data.pricing.nlcPrice)
84
+ : data.pricing?.costPrice
85
+ ? getPriceFromPricingArray(data.pricing.costPrice)
86
+ : 0;
87
+
88
+ // Fallback to old price structure if pricing is not available
89
+ const mrpPrice = mrp || (data.price?.MRP ? getPriceValue(data.price.MRP) : 0);
90
+ const finalSellingPrice = sellingPrice || (data.price?.SP ? getPriceValue(data.price.SP) : 0);
30
91
 
31
92
  const calculateDiscount = () => {
32
- if (!sellingPrice || !mrpPrice || mrpPrice <= sellingPrice) return null;
33
- return Math.round(100 - (sellingPrice / mrpPrice) * 100);
93
+ if (!finalSellingPrice || !mrpPrice || mrpPrice <= finalSellingPrice) return null;
94
+ return Math.round(100 - (finalSellingPrice / mrpPrice) * 100);
34
95
  };
35
96
 
36
97
  const discount = calculateDiscount();
@@ -66,16 +127,16 @@ const ProductListViewTwo = (props: any) => {
66
127
  </div>
67
128
  <div className="card_bottom">
68
129
  <div className="price_container">
69
- {sellingPrice !== 0 && (
130
+ {finalSellingPrice !== 0 && (
70
131
  <>
71
132
  <div className="price_row">
72
- <h4 className="selling_price">₹{sellingPrice.toLocaleString("en-IN")}</h4>
133
+ <h4 className="selling_price">₹{finalSellingPrice.toLocaleString("en-IN")}</h4>
73
134
  {discount !== null && discount > 0 && (
74
135
  <span className="discounts">{discount}% OFF</span>
75
136
  )}
76
137
  </div>
77
- {mrpPrice > sellingPrice && (
78
- <p className="save_amount">Save ₹{(mrpPrice - sellingPrice).toLocaleString("en-IN")}</p>
138
+ {mrpPrice > finalSellingPrice && (
139
+ <p className="save_amount">Save ₹{(mrpPrice - finalSellingPrice).toLocaleString("en-IN")}</p>
79
140
  )}
80
141
  </>
81
142
  )}
@@ -49,7 +49,19 @@ interface TabContentGroup {
49
49
  dynamicImages?: any[];
50
50
  dynamicVideos?: any[];
51
51
  dynamicProducts?: any[];
52
+ staticImages?: any[];
53
+ staticVideos?: any[];
54
+ staticProducts?: any[];
52
55
  showItems?: Product[];
56
+ dynamic?: {
57
+ conditions: any[];
58
+ query: string;
59
+ list: any[];
60
+ pagination: number;
61
+ };
62
+ dynamicQueries?: {
63
+ selectedVariants: any[];
64
+ };
53
65
  }
54
66
 
55
67
  interface TabMode {
@@ -97,10 +109,6 @@ interface HeaderStyle {
97
109
  activeColorText: string;
98
110
  }
99
111
 
100
- interface TabsData {
101
- all: TabItem[];
102
- }
103
-
104
112
  export interface TabComponentProps {
105
113
  name: string;
106
114
  code: string;
@@ -109,7 +117,7 @@ export interface TabComponentProps {
109
117
  showTitle: boolean;
110
118
  title: TitleStyle;
111
119
  header: HeaderStyle;
112
- tabs: TabsData[];
120
+ tabs: TabItem[];
113
121
  }
114
122
 
115
123
  interface TabComponentMainProps {
@@ -157,27 +165,51 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
157
165
  const getImageUrl = (url: string) => {
158
166
  if (!url) return '';
159
167
  if (url.startsWith('http://') || url.startsWith('https://')) return url;
160
- return `${Linodeurl}${url}`;
168
+ // Ensure URL has leading slash if Linodeurl doesn't end with one
169
+ const cleanUrl = url.startsWith('/') ? url : `/${url}`;
170
+ const baseUrl = Linodeurl.endsWith('/') ? Linodeurl.slice(0, -1) : Linodeurl;
171
+ return `${baseUrl}${cleanUrl}`;
172
+ };
173
+
174
+ // Helper function to extract numeric value from price in any format
175
+ const getPriceValue = (price: any): number => {
176
+ console.error(price,"price-----")
177
+ if (price === null || price === undefined) return 0;
178
+
179
+ // If it's already a number
180
+ if (typeof price === 'number') {
181
+ return isNaN(price) ? 0 : price;
182
+ }
183
+
184
+ // If it's an object with $numberDecimal (but not an array)
185
+ if (typeof price === 'object' && price !== null && !Array.isArray(price)) {
186
+ if (price.$numberDecimal !== undefined && price.$numberDecimal !== null) {
187
+ const value = parseFloat(String(price.$numberDecimal));
188
+ return isNaN(value) ? 0 : value;
189
+ }
190
+ }
191
+
192
+ // If it's a string, try to parse it
193
+ if (typeof price === 'string') {
194
+ const value = parseFloat(price);
195
+ return isNaN(value) ? 0 : value;
196
+ }
197
+
198
+ return 0;
161
199
  };
162
200
 
163
201
  // Inline Product Card Component
164
202
  const ProductCard: React.FC<{ product: any; layout?: string }> = ({ product, layout = '1x1' }) => {
165
203
  const formatPrice = (price: any) => {
166
- if (typeof price === 'object' && price.$numberDecimal) {
167
- return parseFloat(price.$numberDecimal).toLocaleString('en-IN', {
168
- style: 'currency',
169
- currency: 'INR',
170
- minimumFractionDigits: 0,
171
- maximumFractionDigits: 0
172
- });
173
- }
174
- return price;
204
+ const priceValue = getPriceValue(price);
205
+ if (priceValue === 0 && !price) return '0';
206
+ return priceValue
175
207
  };
176
208
 
177
209
  const calculateOffer = (mrp: any, sp: any) => {
178
- const mrpValue = parseFloat(mrp.$numberDecimal || mrp);
179
- const spValue = parseFloat(sp.$numberDecimal || sp);
180
- if (mrpValue > spValue) {
210
+ const mrpValue = getPriceValue(mrp);
211
+ const spValue = getPriceValue(sp);
212
+ if (mrpValue > spValue && mrpValue > 0) {
181
213
  const discount = ((mrpValue - spValue) / mrpValue) * 100;
182
214
  return Math.round(discount);
183
215
  }
@@ -204,22 +236,39 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
204
236
  return variant.valueId?.name?.all || variant.valueId?.name || '';
205
237
  };
206
238
 
207
- const mrp = product.price?.MRP;
208
- const sp = product.price?.SP;
239
+ // Use pricing object first, fallback to price for backward compatibility
240
+ const mrp = product.pricing?.mrp ;
241
+ console.error(mrp,product,"mrp-----")
242
+ const sp = product.pricing?.costPrice;
243
+ console.error(sp,"sp-----")
209
244
  const offer = calculateOffer(mrp, sp);
210
245
 
211
246
  const cardMode = layout === '1x1' ? 'carousel-mode' : layout === '2x1' ? 'layout-2x1' : 'grid-mode';
212
247
  const productSlug = product.code;
213
248
  const productLink = `/${productSlug}`;
214
249
 
250
+ // Get product image URL - try multiple possible locations
251
+ const getProductImageUrl = () => {
252
+ return product.image?.all?.url ||
253
+ product.image?.url ||
254
+ product.model?.image?.url ||
255
+ product.model?.image?.all?.url ||
256
+ '';
257
+ };
258
+
215
259
  const cardContent = (
216
260
  <>
217
261
  {/* Product Image */}
218
262
  <div className="product-image-container">
219
263
  <img
220
- src={getImageUrl(product.image?.all?.url || product.model?.image?.url)}
221
- alt={product.name?.all || product.name?.displayName}
264
+ src={getImageUrl(getProductImageUrl())}
265
+ alt={product.name?.all || product.name?.displayName || 'Product image'}
222
266
  className="product-image"
267
+ onError={(e) => {
268
+ // Fallback if image fails to load
269
+ const target = e.target as HTMLImageElement;
270
+ target.style.display = 'none';
271
+ }}
223
272
  />
224
273
  </div>
225
274
 
@@ -266,10 +315,10 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
266
315
  <div className="product-pricing">
267
316
  <div className="price-row">
268
317
  <span className="current-price">{formatPrice(sp)}</span>
269
- {mrp && sp && parseFloat(mrp.$numberDecimal || mrp) > parseFloat(sp.$numberDecimal || sp) && (
318
+ {mrp && sp && offer > 0 && (
270
319
  <>
271
320
  <span className="original-price">{formatPrice(mrp)}</span>
272
- {offer > 0 && <span className="offer-badge">{offer}% OFF</span>}
321
+ <span className="offer-badge">{offer}% OFF</span>
273
322
  </>
274
323
  )}
275
324
  </div>
@@ -432,28 +481,56 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
432
481
 
433
482
  switch (tab.tabContentType) {
434
483
  case 'IMAGE':
435
- if (tab.tabContentImage) {
436
- console.warn(tab.tabContentImage, buildLinkForSlide(tab.tabContentImage));
437
- return (
438
- <a
439
- href={buildLinkForSlide(tab.tabContentImage) || undefined}
440
- target={
441
- tab.tabContentImage.link_type === 'external_link'
442
- ? tab.tabContentImage.external_link?.target
443
- : '_blank'
444
- }
445
- >
446
- <div style={contentStyle}>
447
- <div className="media-box">
448
- <img
449
- src={getImageUrl(tab.tabContentImage.image.url)}
450
- alt={tab.tabContentImage.image.alt}
451
- className="media-content"
452
- />
453
- </div>
484
+ if (tab.tabContentImage && tab.tabContentImage.image) {
485
+ const imageUrl = tab.tabContentImage.image.url;
486
+ const imageAlt = tab.tabContentImage.image.alt || 'Image';
487
+ const fullImageUrl = getImageUrl(imageUrl);
488
+ const linkUrl = buildLinkForSlide(tab.tabContentImage);
489
+ const linkTarget = tab.tabContentImage.link_type === 'EXTERNALLINK'
490
+ ? tab.tabContentImage.external_link?.target || '_blank'
491
+ : '_blank';
492
+
493
+ // Debug: Log image URL construction
494
+ if (!fullImageUrl) {
495
+ console.warn('Image URL is empty. Original URL:', imageUrl);
496
+ }
497
+
498
+ const imageElement = (
499
+ <div style={contentStyle}>
500
+ <div className="media-box" style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
501
+ <img
502
+ src={fullImageUrl}
503
+ alt={imageAlt}
504
+ className="media-content"
505
+ style={{
506
+ width: '100%',
507
+ height: '100%',
508
+ objectFit: 'cover',
509
+ display: 'block'
510
+ }}
511
+ onError={(e) => {
512
+ const target = e.target as HTMLImageElement;
513
+ console.error('Image failed to load. URL:', fullImageUrl, 'Original:', imageUrl);
514
+ target.style.display = 'none';
515
+ }}
516
+ />
454
517
  </div>
518
+ </div>
519
+ );
520
+
521
+ if (linkUrl) {
522
+ return (
523
+ <a
524
+ href={linkUrl}
525
+ target={linkTarget}
526
+ style={{ textDecoration: 'none', color: 'inherit', display: 'contents' }}
527
+ >
528
+ {imageElement}
455
529
  </a>
456
530
  );
531
+ }
532
+
533
+ return imageElement;
457
534
  }
458
535
  break;
459
536
  case 'VIDEO':
@@ -478,7 +555,7 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
478
555
  // Handle both DYNAMIC and STATIC types
479
556
  const images = tab.tabContentGroupImage.type === 'DYNAMIC'
480
557
  ? tab.tabContentGroupImage.dynamicImages
481
- : tab.tabContentGroupImage.showItems;
558
+ : (tab.tabContentGroupImage.staticImages || tab.tabContentGroupImage.showItems);
482
559
 
483
560
  if (!images || images.length === 0) {
484
561
  return <div>No images available</div>;
@@ -818,7 +895,7 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
818
895
  // Handle both DYNAMIC and STATIC types
819
896
  const videos = tab.tabContentGroupVideo.type === 'DYNAMIC'
820
897
  ? tab.tabContentGroupVideo.dynamicVideos
821
- : tab.tabContentGroupVideo.showItems;
898
+ : (tab.tabContentGroupVideo.staticVideos || tab.tabContentGroupVideo.showItems);
822
899
 
823
900
  if (!videos || videos.length === 0) {
824
901
  return <div>No videos available</div>;
@@ -1162,8 +1239,15 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
1162
1239
  break;
1163
1240
 
1164
1241
  case 'GROUPPRODUCT':
1165
- if (tab.tabContentGroupProduct && tab.tabContentGroupProduct.showItems) {
1166
- const products = tab.tabContentGroupProduct.showItems;
1242
+ if (tab.tabContentGroupProduct) {
1243
+ // Handle both DYNAMIC and STATIC types
1244
+ const products = tab.tabContentGroupProduct.type === 'DYNAMIC'
1245
+ ? tab.tabContentGroupProduct.dynamicProducts
1246
+ : ( tab.tabContentGroupProduct.showItems || []);
1247
+
1248
+ if (!products || products.length === 0) {
1249
+ return <div>No products available</div>;
1250
+ }
1167
1251
 
1168
1252
  // 1x1 layout: Carousel view
1169
1253
  if (layout === '1x1') {
@@ -1508,7 +1592,7 @@ const TabComponent: React.FC<TabComponentMainProps> = ({ props, deviceMode = 'we
1508
1592
  return null;
1509
1593
  };
1510
1594
 
1511
- const tabs = props.tabs[0]?.all || [];
1595
+ const tabs = props.tabs || [];
1512
1596
 
1513
1597
  return (
1514
1598
  <div style={{