tee3apps-cms-sdk-react 0.0.15 → 0.0.17

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.
@@ -1,535 +1,617 @@
1
- import React from 'react';
2
- import ProductListViewOne from '../Visual-Components/Styles/ProductListViewOne';
3
- import ProductListViewTwo from '../Visual-Components/Styles/ProductListViewTwo';
4
- import { Linodeurl } from '../../const';
5
-
6
-
7
- interface Product {
8
- _id: string;
9
- code: string;
10
- name: string | { all: string };
11
- image: any;
12
- isActive: boolean;
13
- price?:any;
14
- }
15
-
16
- interface GroupProductStatic {
17
- _id: string;
18
- code: string;
19
- name: string;
20
- }
21
-
22
- interface GroupProductDynamic {
23
- code: string;
24
- name: { all: string };
25
- list: Product[];
26
- isActive: boolean;
27
- }
28
-
29
- interface GroupProductData {
30
- static: GroupProductStatic;
31
- dynamic: GroupProductDynamic;
32
- showItems:Product[]
33
-
34
- }
35
-
36
- interface HeaderTextStyle {
37
- fontSize: number;
38
- fontColor: string;
39
- isBold: boolean;
40
- isItalic: boolean;
41
- isUnderline: boolean;
42
- }
43
-
44
- interface DeviceBooleanProps {
45
- web: boolean;
46
- mobileweb: boolean;
47
- mobileapp: boolean;
48
- tablet: boolean;
49
- }
50
-
51
- interface DeviceLayoutProps {
52
- web: string;
53
- mobileweb: string;
54
- mobileapp: string;
55
- tablet: string;
56
- }
57
-
58
- export interface GroupProductComponentProps {
59
- headerText: { all: string };
60
- type: string;
61
- groupproduct: GroupProductData;
62
- showItems:Product[]
63
- activeStatus: boolean;
64
- headerImage: string;
65
- selectedProducts: Product[];
66
- items: any[];
67
-
68
- cardColor: string;
69
- showProductName: DeviceBooleanProps;
70
- headerTextStyle: HeaderTextStyle;
71
- layout: DeviceLayoutProps;
72
- style: DeviceLayoutProps;
73
-
74
- showHeader: DeviceBooleanProps;
75
- isHorizontalScroll: DeviceBooleanProps;
76
- headerBackground: string;
77
- viewAllLink?: string;
78
- }
79
-
80
- interface GroupProductComponentMainProps {
81
- props: GroupProductComponentProps;
82
- deviceMode?: string;
83
- }
84
-
85
- const GroupProductComponent: React.FC<GroupProductComponentMainProps> = ({
86
- props,
87
- deviceMode = 'web'
88
- }) => {
89
- const getCurrentBooleanProp = (prop: DeviceBooleanProps) => {
90
- switch(deviceMode) {
91
- case 'mobileweb': return prop.mobileweb;
92
- case 'mobileapp': return prop.mobileapp;
93
- case 'tablet': return prop.tablet;
94
- case 'web':
95
- default: return prop.web;
96
- }
97
- };
98
-
99
- const getCurrentLayout = () => {
100
- switch(deviceMode) {
101
- case 'mobileweb': return props.layout.mobileweb;
102
- case 'mobileapp': return props.layout.mobileapp;
103
- case 'tablet': return props.layout.tablet;
104
- case 'web':
105
- default: return props.layout.web;
106
- }
107
- };
108
-
109
- const getCurrentStyle = () => {
110
- switch(deviceMode) {
111
- case 'mobileweb': return props.style.mobileweb;
112
- case 'mobileapp': return props.style.mobileapp;
113
- case 'tablet': return props.style.tablet;
114
- case 'web':
115
- default: return props.style.web;
116
- }
117
- };
118
- const showHeader = getCurrentBooleanProp(props.showHeader);
119
- const showProductName = getCurrentBooleanProp(props.showProductName);
120
- const isHorizontalScroll = getCurrentBooleanProp(props.isHorizontalScroll);
121
- const currentLayout = getCurrentLayout();
122
- const currentstyle=getCurrentStyle();
123
-
124
- const getProducts = () => {
125
- if(props?.groupproduct?.showItems) return props.groupproduct.showItems
126
- return [];
127
- };
128
-
129
- const products = getProducts();
130
-
131
- // Helper function to render product based on style
132
- const renderProduct = (product: Product, key: string) => {
133
- if (currentstyle === 'STYLE1') {
134
- return (
135
- <div key={key}>
136
- <ProductListViewOne props={product} />
137
- </div>
138
- );
139
- } else if (currentstyle === 'STYLE2') {
140
- return (
141
- <div key={key}>
142
- <ProductListViewTwo props={product} />
143
- </div>
144
- );
145
- } else {
146
- // Default style (NONE) - inline JSX
147
- return (
148
- <a href={`/${product.code}`} target={'_blank'} rel="noopener noreferrer" style={{textDecoration:"none"}} key={key}>
149
- <div
150
- className="productImageSlide"
151
- style={{
152
- height: 'auto',
153
- minWidth: deviceMode === 'mobileapp' || deviceMode === 'mobileweb' ? '120px' : '150px',
154
- borderRadius: '8px',
155
- overflow: 'hidden',
156
- border: '1px solid #eee',
157
- backgroundColor: '#fff',
158
- display: 'flex',
159
- flexDirection: 'column',
160
- alignItems: 'center',
161
- justifyContent: 'center',
162
- padding: '12px',
163
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
164
- transition: 'transform 0.2s ease',
165
- cursor: 'pointer',
166
- }}
167
- onMouseOver={(e) => {
168
- e.currentTarget.style.transform = 'translateY(-2px)';
169
- e.currentTarget.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
170
- }}
171
- onMouseOut={(e) => {
172
- e.currentTarget.style.transform = 'translateY(0)';
173
- e.currentTarget.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
174
- }}
175
- >
176
- <div
177
- style={{
178
- height: '120px',
179
- width: '100%',
180
- display: 'flex',
181
- alignItems: 'center',
182
- justifyContent: 'center',
183
- marginBottom: '8px',
184
- }}
185
- >
186
- <img
187
- src={`${Linodeurl}${product.image?.url}`}
188
- alt={typeof product.name === 'object' ? product.name.all : product.name}
189
- style={{ width: '100%', height: '100%', objectFit: 'contain' }}
190
- />
191
- </div>
192
-
193
- {showProductName && (
194
- <div
195
- style={{
196
- marginTop: '8px',
197
- textAlign: 'center',
198
- fontSize: '14px',
199
- fontWeight: '500',
200
- color: '#333',
201
- lineHeight: '1.4',
202
- height: '40px',
203
- overflow: 'hidden',
204
- display: '-webkit-box',
205
- WebkitLineClamp: 2,
206
- WebkitBoxOrient: 'vertical',
207
- }}
208
- >
209
- {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>
213
- </div>
214
- )}
215
- </div>
216
- </a>
217
- );
218
- }
219
- };
220
-
221
- // Helper function to render product card (for grid layouts)
222
- const renderProductCard = (product: Product, key: string, imageHeight: string = '120px', fontSize: string = '14px', nameHeight: string = '40px', fontWeight: string = '500') => {
223
- if (currentstyle === 'STYLE1') {
224
- return (
225
- <div key={key}>
226
- <ProductListViewOne props={product} />
227
- </div>
228
- );
229
- } else if (currentstyle === 'STYLE2') {
230
- return (
231
- <div key={key}>
232
- <ProductListViewTwo props={product} />
233
- </div>
234
- );
235
- } else {
236
- // Default style (NONE) - inline JSX
237
- return (
238
- <div
239
- key={key}
240
- className="productImageSlide"
241
- style={{
242
- height: 'auto',
243
- borderRadius: '8px',
244
- overflow: 'hidden',
245
- border: '1px solid #eee',
246
- backgroundColor: '#fff',
247
- display: 'flex',
248
- flexDirection: 'column',
249
- alignItems: 'center',
250
- justifyContent: 'center',
251
- padding: '12px',
252
- boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
253
- transition: 'transform 0.2s ease',
254
- cursor: 'pointer'
255
- }}
256
- onMouseOver={(e) => {
257
- e.currentTarget.style.transform = 'translateY(-2px)';
258
- e.currentTarget.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
259
- }}
260
- onMouseOut={(e) => {
261
- e.currentTarget.style.transform = 'translateY(0)';
262
- e.currentTarget.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
263
- }}
264
- >
265
- <div style={{
266
- height: imageHeight,
267
- width: '100%',
268
- display: 'flex',
269
- alignItems: 'center',
270
- justifyContent: 'center',
271
- marginBottom: '8px'
272
- }}>
273
- <img
274
- src={`${Linodeurl}${product.image?.all?.url || product.image?.url}`}
275
- alt=""
276
- style={{ width: '100%', height: '100%', objectFit: 'contain' }}
277
- />
278
- </div>
279
- {showProductName && <div style={{
280
- textAlign: 'center',
281
- fontSize: fontSize,
282
- fontWeight: fontWeight,
283
- color: '#333',
284
- lineHeight: '1.4',
285
- ...(nameHeight === 'auto' ? {} : {
286
- height: nameHeight,
287
- overflow: 'hidden',
288
- display: '-webkit-box',
289
- WebkitLineClamp: 2,
290
- WebkitBoxOrient: 'vertical'
291
- })
292
- }}>
293
- {typeof product.name === 'object' ? (product.name as { all: string }).all : product.name}
294
- </div>}
295
- </div>
296
- );
297
- }
298
- };
299
-
300
- // Carousel navigation functions
301
- const scrollLeft = () => {
302
- const carousel = document.querySelector('.groupProductCarousel');
303
- if (carousel) {
304
- carousel.scrollBy({ left: -200, behavior: 'smooth' });
305
- }
306
- };
307
-
308
- const scrollRight = () => {
309
- const carousel = document.querySelector('.groupProductCarousel');
310
- if (carousel) {
311
- carousel.scrollBy({ left: 200, behavior: 'smooth' });
312
- }
313
- };
314
-
315
- return (
316
- <div
317
- style={{
318
- border: '1px solid #e1e1e1',
319
- width: '100%',
320
- maxWidth: '100%',
321
- borderRadius: '0px',
322
- minHeight: '100px',
323
- position: 'relative',
324
- overflow: 'hidden',
325
- marginBottom:'20px',
326
- marginTop:'0px'
327
-
328
- }}
329
- className='GroupProductComponent'
330
- >
331
- {showHeader && (
332
- <div
333
- className="groupProductHeader"
334
- style={{
335
- backgroundColor: props.headerBackground,
336
- padding: '12px 16px',
337
- borderRadius: '0px',
338
- marginBottom: '4px',
339
- display: 'flex',
340
- alignItems: 'center',
341
- justifyContent: 'space-between',
342
- flexWrap: 'wrap',
343
- gap: '12px',
344
- }}
345
- >
346
- <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
347
- {props.headerImage && (
348
- <div style={{ width: '32px', height: '32px' }}>
349
- {/* <ImageDisplayComponent
350
- fileUrl={props.headerImage}
351
- preserveAspectRatio={true}
352
- maxWidth="100%"
353
- maxHeight="32px"
354
- /> */}
355
- <img
356
- src={`${Linodeurl}${props.headerImage}`}
357
- style={{ width: '100%', height: '100%', objectFit: 'cover' }}
358
- />
359
- </div>
360
- )}
361
- <p style={{
362
- color: props.headerTextStyle.fontColor,
363
- fontSize: `${props.headerTextStyle.fontSize}px`,
364
- fontWeight: props.headerTextStyle.isBold ? 'bold' : 'normal',
365
- fontStyle: props.headerTextStyle.isItalic ? 'italic' : 'normal',
366
- textDecoration: props.headerTextStyle.isUnderline ? 'underline' : 'none',
367
- margin: 0
368
- }}>
369
- {props.headerText?.all || 'Header text'}
370
- </p>
371
- </div>
372
-
373
- <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
374
-
375
- {props.type=='static' && (
376
- <a
377
- href={`http://localhost:5173/${props.groupproduct.static.code}/s?type=groupproduct`}
378
- target="_blank"
379
- rel="noopener noreferrer"
380
- style={{
381
- color: 'black',
382
- textDecoration: 'none',
383
- fontWeight: '500',
384
- fontSize: '14px',
385
- padding: '6px 12px',
386
- border: 'none',
387
- borderRadius: '4px',
388
- backgroundColor: 'transparent',
389
- cursor: 'pointer'
390
- }}
391
- >
392
- View All
393
- </a>
394
- )}
395
-
396
-
397
-
398
-
399
- {currentLayout === 'NONE' && products.length > 4 && (
400
- <div style={{ display: 'flex', gap: '8px' }}>
401
- <button
402
- onClick={scrollLeft}
403
- style={{
404
- width: '32px',
405
- height: '32px',
406
- borderRadius: '50%',
407
- border: '1px solid #ddd',
408
- backgroundColor: '#fff',
409
- cursor: 'pointer',
410
- display: 'flex',
411
- alignItems: 'center',
412
- justifyContent: 'center',
413
- fontSize: '16px',
414
- fontWeight: 'bold'
415
- }}
416
- onMouseOver={(e) => {
417
- e.currentTarget.style.backgroundColor = '#f8f9fa';
418
- }}
419
- onMouseOut={(e) => {
420
- e.currentTarget.style.backgroundColor = '#fff';
421
- }}
422
- >
423
- &#8249;
424
- </button>
425
- <button
426
- onClick={scrollRight}
427
- style={{
428
- width: '32px',
429
- height: '32px',
430
- borderRadius: '50%',
431
- border: '1px solid #ddd',
432
- backgroundColor: '#fff',
433
- cursor: 'pointer',
434
- display: 'flex',
435
- alignItems: 'center',
436
- justifyContent: 'center',
437
- fontSize: '16px',
438
- fontWeight: 'bold'
439
- }}
440
- onMouseOver={(e) => {
441
- e.currentTarget.style.backgroundColor = '#f8f9fa';
442
- }}
443
- onMouseOut={(e) => {
444
- e.currentTarget.style.backgroundColor = '#fff';
445
- }}
446
- >
447
- &#8250;
448
- </button>
449
- </div>
450
- )}
451
- </div>
452
- </div>
453
- )}
454
-
455
- <div
456
- className="groupProductCarousel"
457
- style={{
458
- display: currentLayout === 'NONE' ? 'flex' : 'block',
459
- overflowX: currentLayout === 'NONE' && isHorizontalScroll ? 'auto' : 'visible',
460
- gap: currentLayout === 'NONE' ? '12px' : '0',
461
- padding: '12px',
462
- scrollBehavior: 'smooth',
463
- backgroundColor: props.cardColor || '#fff',
464
- scrollbarWidth: 'thin',
465
- borderRadius: '8px',
466
- position: 'relative',
467
- scrollbarColor: '#c1c1c1 transparent'
468
- }}
469
- >
470
- {products.length > 0 ? (
471
- currentLayout === 'NONE' ? (
472
- products.slice(0, props.type === 'static' ? 15 : products.length).map((product) =>
473
- renderProduct(product, product._id)
474
- )
475
- ) : currentLayout === 'SMALL' ? (
476
- <div style={{
477
- display: 'grid',
478
- gridTemplateColumns: 'repeat(2, 1fr)',
479
- gap: '16px',
480
- padding: '8px'
481
- }}>
482
- {
483
- products.map((product) =>
484
- renderProductCard(product, product._id, '100px', '12px', '32px')
485
- )}
486
- </div>
487
- ) : currentLayout === 'MEDIUM' ? (
488
- <div style={{
489
- display: 'grid',
490
- gridTemplateColumns: 'repeat(3, 1fr)',
491
- gap: '16px',
492
- padding: '8px'
493
- }}>
494
- {
495
- products.map((product) =>
496
- renderProductCard(product, product._id, '120px', '14px', '40px')
497
- )}
498
- </div>
499
- ) : currentLayout === 'MEDIUM_THREE' ? (
500
- <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '8px' }}>
501
- {products.length > 0 && (
502
- renderProductCard(products[0], products[0]._id, '160px', '16px', 'auto', '600')
503
- )}
504
- {products.length > 1 && (
505
- <div style={{
506
- display: 'grid',
507
- gridTemplateColumns: 'repeat(2,1fr)',
508
- gap: '16px'
509
- }}>
510
- {products.slice(1).map((product) =>
511
- renderProductCard(product, product._id, '100px', '12px', '32px', '500')
512
- )}
513
- </div>
514
- )}
515
- </div>
516
- ) : null
517
- ) : (
518
- <div style={{
519
- textAlign: 'center',
520
- color: '#666',
521
- padding: '40px',
522
- width: '100%',
523
- border: '2px dashed #ddd',
524
- borderRadius: '8px',
525
- backgroundColor: '#f9f9f9'
526
- }}>
527
- <p>No products selected. Use settings to add products.</p>
528
- </div>
529
- )}
530
- </div>
531
- </div>
532
- );
533
- };
534
-
1
+ import React from 'react';
2
+ import ProductListViewOne from '../Visual-Components/Styles/ProductListViewOne';
3
+ import ProductListViewTwo from '../Visual-Components/Styles/ProductListViewTwo';
4
+ import { Linodeurl } from '../../const';
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
+
83
+
84
+ interface Product {
85
+ _id: string;
86
+ code: string;
87
+ name: string | { all: string };
88
+ image: any;
89
+ isActive: boolean;
90
+ price?:any;
91
+ }
92
+
93
+ interface GroupProductStatic {
94
+ _id: string;
95
+ code: string;
96
+ name: string;
97
+ }
98
+
99
+ interface GroupProductDynamic {
100
+ code: string;
101
+ name: { all: string };
102
+ list: Product[];
103
+ isActive: boolean;
104
+ }
105
+
106
+ interface GroupProductData {
107
+ static: GroupProductStatic;
108
+ dynamic: GroupProductDynamic;
109
+ showItems:Product[]
110
+
111
+ }
112
+
113
+ interface HeaderTextStyle {
114
+ fontSize: number;
115
+ fontColor: string;
116
+ isBold: boolean;
117
+ isItalic: boolean;
118
+ isUnderline: boolean;
119
+ }
120
+
121
+ interface DeviceBooleanProps {
122
+ web: boolean;
123
+ mobileweb: boolean;
124
+ mobileapp: boolean;
125
+ tablet: boolean;
126
+ }
127
+
128
+ interface DeviceLayoutProps {
129
+ web: string;
130
+ mobileweb: string;
131
+ mobileapp: string;
132
+ tablet: string;
133
+ }
134
+
135
+ export interface GroupProductComponentProps {
136
+ headerText: any;
137
+ type: string;
138
+ groupproduct: GroupProductData;
139
+ showItems:Product[]
140
+ activeStatus: boolean;
141
+ headerImage: string;
142
+ selectedProducts: Product[];
143
+ items: any[];
144
+
145
+ cardColor: string;
146
+ showProductName: DeviceBooleanProps;
147
+ headerTextStyle: HeaderTextStyle;
148
+ layout: DeviceLayoutProps;
149
+ style: DeviceLayoutProps;
150
+
151
+ showHeader: DeviceBooleanProps;
152
+ isHorizontalScroll: DeviceBooleanProps;
153
+ headerBackground: string;
154
+ viewAllLink?: string;
155
+ }
156
+
157
+ interface GroupProductComponentMainProps {
158
+ props: GroupProductComponentProps;
159
+ deviceMode?: string;
160
+ }
161
+
162
+ const GroupProductComponent: React.FC<GroupProductComponentMainProps> = ({
163
+ props,
164
+ deviceMode = 'web'
165
+ }) => {
166
+ const getCurrentBooleanProp = (prop: DeviceBooleanProps) => {
167
+ switch(deviceMode) {
168
+ case 'mobileweb': return prop.mobileweb;
169
+ case 'mobileapp': return prop.mobileapp;
170
+ case 'tablet': return prop.tablet;
171
+ case 'web':
172
+ default: return prop.web;
173
+ }
174
+ };
175
+
176
+ const getCurrentLayout = () => {
177
+ switch(deviceMode) {
178
+ case 'mobileweb': return props.layout.mobileweb;
179
+ case 'mobileapp': return props.layout.mobileapp;
180
+ case 'tablet': return props.layout.tablet;
181
+ case 'web':
182
+ default: return props.layout.web;
183
+ }
184
+ };
185
+
186
+ const getCurrentStyle = () => {
187
+ switch(deviceMode) {
188
+ case 'mobileweb': return props.style.mobileweb;
189
+ case 'mobileapp': return props.style.mobileapp;
190
+ case 'tablet': return props.style.tablet;
191
+ case 'web':
192
+ default: return props.style.web;
193
+ }
194
+ };
195
+ const showHeader = getCurrentBooleanProp(props.showHeader);
196
+ const showProductName = getCurrentBooleanProp(props.showProductName);
197
+ const isHorizontalScroll = getCurrentBooleanProp(props.isHorizontalScroll);
198
+ const currentLayout = getCurrentLayout();
199
+ const currentstyle=getCurrentStyle();
200
+
201
+ const getProducts = () => {
202
+ if(props?.groupproduct?.showItems) return props.groupproduct.showItems
203
+ return [];
204
+ };
205
+
206
+ const products = getProducts();
207
+
208
+ // Helper function to render product based on style
209
+ const renderProduct = (product: Product, key: string) => {
210
+ if (currentstyle === 'STYLE1') {
211
+ return (
212
+ <div key={key}>
213
+ <ProductListViewOne props={product} />
214
+ </div>
215
+ );
216
+ } else if (currentstyle === 'STYLE2') {
217
+ return (
218
+ <div key={key}>
219
+ <ProductListViewTwo props={product} />
220
+ </div>
221
+ );
222
+ } else {
223
+ // Default style (NONE) - inline JSX
224
+ return (
225
+ <a href={`/${product.code}`} target={'_blank'} rel="noopener noreferrer" style={{textDecoration:"none"}} key={key}>
226
+ <div
227
+ className="productImageSlide"
228
+ style={{
229
+ height: 'auto',
230
+ minWidth: deviceMode === 'mobileapp' || deviceMode === 'mobileweb' ? '120px' : '150px',
231
+ borderRadius: '8px',
232
+ overflow: 'hidden',
233
+ border: '1px solid #eee',
234
+ backgroundColor: '#fff',
235
+ display: 'flex',
236
+ flexDirection: 'column',
237
+ alignItems: 'center',
238
+ justifyContent: 'center',
239
+ padding: '12px',
240
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
241
+ transition: 'transform 0.2s ease',
242
+ cursor: 'pointer',
243
+ }}
244
+ onMouseOver={(e) => {
245
+ e.currentTarget.style.transform = 'translateY(-2px)';
246
+ e.currentTarget.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
247
+ }}
248
+ onMouseOut={(e) => {
249
+ e.currentTarget.style.transform = 'translateY(0)';
250
+ e.currentTarget.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
251
+ }}
252
+ >
253
+ <div
254
+ style={{
255
+ height: '120px',
256
+ width: '100%',
257
+ display: 'flex',
258
+ alignItems: 'center',
259
+ justifyContent: 'center',
260
+ marginBottom: '8px',
261
+ }}
262
+ >
263
+ <img
264
+ src={`${Linodeurl}${product.image?.url}`}
265
+ alt={typeof product.name === 'object' ? product.name.all : product.name}
266
+ style={{ width: '100%', height: '100%', objectFit: 'contain' }}
267
+ />
268
+ </div>
269
+
270
+ {showProductName && (
271
+ <div
272
+ style={{
273
+ marginTop: '8px',
274
+ textAlign: 'center',
275
+ fontSize: '14px',
276
+ fontWeight: '500',
277
+ color: '#333',
278
+ lineHeight: '1.4',
279
+ height: '40px',
280
+ overflow: 'hidden',
281
+ display: '-webkit-box',
282
+ WebkitLineClamp: 2,
283
+ WebkitBoxOrient: 'vertical',
284
+ }}
285
+ >
286
+ {typeof product.name === 'object' ? product.name.all : product.name}
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
+ })()}
295
+ </div>
296
+ )}
297
+ </div>
298
+ </a>
299
+ );
300
+ }
301
+ };
302
+
303
+ // Helper function to render product card (for grid layouts)
304
+ const renderProductCard = (product: Product, key: string, imageHeight: string = '120px', fontSize: string = '14px', nameHeight: string = '40px', fontWeight: string = '500') => {
305
+ if (currentstyle === 'STYLE1') {
306
+ return (
307
+ <div key={key}>
308
+ <ProductListViewOne props={product} />
309
+ </div>
310
+ );
311
+ } else if (currentstyle === 'STYLE2') {
312
+ return (
313
+ <div key={key}>
314
+ <ProductListViewTwo props={product} />
315
+ </div>
316
+ );
317
+ } else {
318
+ // Default style (NONE) - inline JSX
319
+ return (
320
+ <div
321
+ key={key}
322
+ className="productImageSlide"
323
+ style={{
324
+ height: 'auto',
325
+ borderRadius: '8px',
326
+ overflow: 'hidden',
327
+ border: '1px solid #eee',
328
+ backgroundColor: '#fff',
329
+ display: 'flex',
330
+ flexDirection: 'column',
331
+ alignItems: 'center',
332
+ justifyContent: 'center',
333
+ padding: '12px',
334
+ boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
335
+ transition: 'transform 0.2s ease',
336
+ cursor: 'pointer'
337
+ }}
338
+ onMouseOver={(e) => {
339
+ e.currentTarget.style.transform = 'translateY(-2px)';
340
+ e.currentTarget.style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
341
+ }}
342
+ onMouseOut={(e) => {
343
+ e.currentTarget.style.transform = 'translateY(0)';
344
+ e.currentTarget.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
345
+ }}
346
+ >
347
+ <div style={{
348
+ height: imageHeight,
349
+ width: '100%',
350
+ display: 'flex',
351
+ alignItems: 'center',
352
+ justifyContent: 'center',
353
+ marginBottom: '8px'
354
+ }}>
355
+ <img
356
+ src={`${Linodeurl}${product.image?.all?.url || product.image?.url}`}
357
+ alt=""
358
+ style={{ width: '100%', height: '100%', objectFit: 'contain' }}
359
+ />
360
+ </div>
361
+ {showProductName && <div style={{
362
+ textAlign: 'center',
363
+ fontSize: fontSize,
364
+ fontWeight: fontWeight,
365
+ color: '#333',
366
+ lineHeight: '1.4',
367
+ ...(nameHeight === 'auto' ? {} : {
368
+ height: nameHeight,
369
+ overflow: 'hidden',
370
+ display: '-webkit-box',
371
+ WebkitLineClamp: 2,
372
+ WebkitBoxOrient: 'vertical'
373
+ })
374
+ }}>
375
+ {typeof product.name === 'object' ? (product.name as { all: string }).all : product.name}
376
+ </div>}
377
+ </div>
378
+ );
379
+ }
380
+ };
381
+
382
+ // Carousel navigation functions
383
+ const scrollLeft = () => {
384
+ const carousel = document.querySelector('.groupProductCarousel');
385
+ if (carousel) {
386
+ carousel.scrollBy({ left: -200, behavior: 'smooth' });
387
+ }
388
+ };
389
+
390
+ const scrollRight = () => {
391
+ const carousel = document.querySelector('.groupProductCarousel');
392
+ if (carousel) {
393
+ carousel.scrollBy({ left: 200, behavior: 'smooth' });
394
+ }
395
+ };
396
+
397
+ return (
398
+ <div
399
+ style={{
400
+ border: '1px solid #e1e1e1',
401
+ width: '100%',
402
+ maxWidth: '100%',
403
+ borderRadius: '0px',
404
+ minHeight: '100px',
405
+ position: 'relative',
406
+ overflow: 'hidden',
407
+ marginBottom:'20px',
408
+ marginTop:'0px'
409
+
410
+ }}
411
+ className='GroupProductComponent'
412
+ >
413
+ {showHeader && (
414
+ <div
415
+ className="groupProductHeader"
416
+ style={{
417
+ backgroundColor: props.headerBackground,
418
+ padding: '12px 16px',
419
+ borderRadius: '0px',
420
+ marginBottom: '4px',
421
+ display: 'flex',
422
+ alignItems: 'center',
423
+ justifyContent: 'space-between',
424
+ flexWrap: 'wrap',
425
+ gap: '12px',
426
+ }}
427
+ >
428
+ <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
429
+ {props.headerImage && (
430
+ <div style={{ width: '32px', height: '32px' }}>
431
+ {/* <ImageDisplayComponent
432
+ fileUrl={props.headerImage}
433
+ preserveAspectRatio={true}
434
+ maxWidth="100%"
435
+ maxHeight="32px"
436
+ /> */}
437
+ <img
438
+ src={`${Linodeurl}${props.headerImage}`}
439
+ style={{ width: '100%', height: '100%', objectFit: 'cover' }}
440
+ />
441
+ </div>
442
+ )}
443
+ <p style={{
444
+ color: props.headerTextStyle.fontColor,
445
+ fontSize: `${props.headerTextStyle.fontSize}px`,
446
+ fontWeight: props.headerTextStyle.isBold ? 'bold' : 'normal',
447
+ fontStyle: props.headerTextStyle.isItalic ? 'italic' : 'normal',
448
+ textDecoration: props.headerTextStyle.isUnderline ? 'underline' : 'none',
449
+ margin: 0
450
+ }}>
451
+ {props.headerText?.all || props?.headerText}
452
+ </p>
453
+ </div>
454
+
455
+ <div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
456
+
457
+ {/* {props.type=='static' && (
458
+ <a
459
+ href={`http://localhost:5173/${props.groupproduct.static.code}/s?type=groupproduct`}
460
+ target="_blank"
461
+ rel="noopener noreferrer"
462
+ style={{
463
+ color: 'black',
464
+ textDecoration: 'none',
465
+ fontWeight: '500',
466
+ fontSize: '14px',
467
+ padding: '6px 12px',
468
+ border: 'none',
469
+ borderRadius: '4px',
470
+ backgroundColor: 'transparent',
471
+ cursor: 'pointer'
472
+ }}
473
+ >
474
+ View All
475
+ </a>
476
+ )} */}
477
+
478
+
479
+
480
+
481
+ {currentLayout === 'NONE' && products.length > 4 && (
482
+ <div style={{ display: 'flex', gap: '8px' }}>
483
+ <button
484
+ onClick={scrollLeft}
485
+ style={{
486
+ width: '32px',
487
+ height: '32px',
488
+ borderRadius: '50%',
489
+ border: '1px solid #ddd',
490
+ backgroundColor: '#fff',
491
+ cursor: 'pointer',
492
+ display: 'flex',
493
+ alignItems: 'center',
494
+ justifyContent: 'center',
495
+ fontSize: '16px',
496
+ fontWeight: 'bold'
497
+ }}
498
+ onMouseOver={(e) => {
499
+ e.currentTarget.style.backgroundColor = '#f8f9fa';
500
+ }}
501
+ onMouseOut={(e) => {
502
+ e.currentTarget.style.backgroundColor = '#fff';
503
+ }}
504
+ >
505
+ &#8249;
506
+ </button>
507
+ <button
508
+ onClick={scrollRight}
509
+ style={{
510
+ width: '32px',
511
+ height: '32px',
512
+ borderRadius: '50%',
513
+ border: '1px solid #ddd',
514
+ backgroundColor: '#fff',
515
+ cursor: 'pointer',
516
+ display: 'flex',
517
+ alignItems: 'center',
518
+ justifyContent: 'center',
519
+ fontSize: '16px',
520
+ fontWeight: 'bold'
521
+ }}
522
+ onMouseOver={(e) => {
523
+ e.currentTarget.style.backgroundColor = '#f8f9fa';
524
+ }}
525
+ onMouseOut={(e) => {
526
+ e.currentTarget.style.backgroundColor = '#fff';
527
+ }}
528
+ >
529
+ &#8250;
530
+ </button>
531
+ </div>
532
+ )}
533
+ </div>
534
+ </div>
535
+ )}
536
+
537
+ <div
538
+ className="groupProductCarousel"
539
+ style={{
540
+ display: currentLayout === 'NONE' ? 'flex' : 'block',
541
+ overflowX: currentLayout === 'NONE' && isHorizontalScroll ? 'auto' : 'visible',
542
+ gap: currentLayout === 'NONE' ? '12px' : '0',
543
+ padding: '12px',
544
+ scrollBehavior: 'smooth',
545
+ backgroundColor: props.cardColor || '#fff',
546
+ scrollbarWidth: 'thin',
547
+ borderRadius: '8px',
548
+ position: 'relative',
549
+ scrollbarColor: '#c1c1c1 transparent'
550
+ }}
551
+ >
552
+ {products.length > 0 ? (
553
+ currentLayout === 'NONE' ? (
554
+ products.slice(0, props.type === 'static' ? 15 : products.length).map((product) =>
555
+ renderProduct(product, product._id)
556
+ )
557
+ ) : currentLayout === 'SMALL' ? (
558
+ <div style={{
559
+ display: 'grid',
560
+ gridTemplateColumns: 'repeat(2, 1fr)',
561
+ gap: '16px',
562
+ padding: '8px'
563
+ }}>
564
+ {
565
+ products.map((product) =>
566
+ renderProductCard(product, product._id, '100px', '12px', '32px')
567
+ )}
568
+ </div>
569
+ ) : currentLayout === 'MEDIUM' ? (
570
+ <div style={{
571
+ display: 'grid',
572
+ gridTemplateColumns: 'repeat(3, 1fr)',
573
+ gap: '16px',
574
+ padding: '8px'
575
+ }}>
576
+ {
577
+ products.map((product) =>
578
+ renderProductCard(product, product._id, '120px', '14px', '40px')
579
+ )}
580
+ </div>
581
+ ) : currentLayout === 'MEDIUM_THREE' ? (
582
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '8px' }}>
583
+ {products.length > 0 && (
584
+ renderProductCard(products[0], products[0]._id, '160px', '16px', 'auto', '600')
585
+ )}
586
+ {products.length > 1 && (
587
+ <div style={{
588
+ display: 'grid',
589
+ gridTemplateColumns: 'repeat(2,1fr)',
590
+ gap: '16px'
591
+ }}>
592
+ {products.slice(1).map((product) =>
593
+ renderProductCard(product, product._id, '100px', '12px', '32px', '500')
594
+ )}
595
+ </div>
596
+ )}
597
+ </div>
598
+ ) : null
599
+ ) : (
600
+ <div style={{
601
+ textAlign: 'center',
602
+ color: '#666',
603
+ padding: '40px',
604
+ width: '100%',
605
+ border: '2px dashed #ddd',
606
+ borderRadius: '8px',
607
+ backgroundColor: '#f9f9f9'
608
+ }}>
609
+ <p>No products selected. Use settings to add products.</p>
610
+ </div>
611
+ )}
612
+ </div>
613
+ </div>
614
+ );
615
+ };
616
+
535
617
  export default GroupProductComponent;