tee3apps-cms-sdk-react 0.0.33 → 0.0.35

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.33",
3
+ "version": "0.0.35",
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",
package/src/Page.tsx CHANGED
@@ -8,7 +8,7 @@ import GroupProductComponent, { GroupProductComponentProps } from './PageCompone
8
8
  import VideoComponent, { VideoComponentProps } from './PageComponents/Visual-Components/VideoComponent';
9
9
  import GroupBrandComponent, { GroupBrandComponentProps } from './PageComponents/Visual-Components/GroupBrandComponent';
10
10
  import LottieComponent, { LottieComponentProps } from './PageComponents/Visual-Components/LottieComponent';
11
- import { ImageComponentProps, LinkProps, TextProps } from './common.interface';
11
+ import { ImageComponentProps, LinkProps, TextProps } from './common.interface';
12
12
  import CarouselComponent, { CarouselProps } from './PageComponents/Visual-Components/CarouselComponent';
13
13
  import NavigationComponent, { NavigationProps } from './PageComponents/Visual-Components/NavigationComponent';
14
14
  import './index.css'
@@ -18,9 +18,9 @@ import GroupImageList, { GroupImageListProps } from './PageComponents/Visual-Com
18
18
  import TabComponent, { TabComponentProps } from './PageComponents/Visual-Components/TabComponent';
19
19
  import ErrorBoundary from './ErrorBoundary';
20
20
  import RichTextComponent, { RichTextComponentProps } from './PageComponents/Visual-Components/RichTextComponent';
21
- const Page = ({data}:any) => {
22
- const [deviceMode, setDeviceMode] = useState<string>('web');
23
- const [screenSize, setScreenSize] = useState({
21
+ const Page = ({ data, showsp = true, showdiscount = true }: any) => {
22
+ const [deviceMode, setDeviceMode] = useState<string>('web');
23
+ const [screenSize, setScreenSize] = useState({
24
24
  width: 0,
25
25
  height: 0
26
26
  });
@@ -53,73 +53,93 @@ const Page = ({data}:any) => {
53
53
  return (
54
54
  <>
55
55
  <div className=''>
56
- <div className=''>
57
-
58
- <ErrorBoundary>
59
- {data.map((row: { props: any; columns: any[]; }, rowIndex: React.Key | null | undefined) => (
60
- <RowComponent key={rowIndex} props={row.props} deviceMode={deviceMode}>
61
- {row.columns.map((box, boxIndex) => (
62
- <BoxComponent
63
- key={boxIndex}
64
- props={box.props}
65
- deviceMode={deviceMode}
66
- autoAdjustForImages={false}
67
- >
68
- {box.components.map((component: { name: string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined; props: TextProps | LinkProps | ImageComponentProps | GroupProductComponentProps | VideoComponentProps | GroupBrandComponentProps | LottieComponentProps | CarouselProps | NavigationProps | GroupVideoListProps | GroupCategoryComponentProps | GroupImageListProps | TabComponentProps | RichTextComponentProps; }, compIndex: React.Key | null | undefined) => {
69
- const getCurrentBoxHeight = () => {
70
- const validModes = ['web', 'mobileweb', 'mobileapp', 'tablet'] as const;
71
- const safeDeviceMode = validModes.includes(deviceMode as any)
72
- ? deviceMode as keyof typeof box.props.mode
73
- : 'web';
74
- if(component.name==='ImageComponent') return 'auto' // add this line
75
- return box.props.mode[safeDeviceMode]?.height || 'auto';
76
- };
56
+ <div className=''>
77
57
 
78
- try {
79
- switch (component.name) {
80
- case 'TextComponent':
81
- return <TextComponent key={compIndex} props={component.props as TextProps} />;
82
- case 'LinkComponent':
83
- return <LinkComponent key={compIndex} props={component.props as LinkProps} />;
84
- case 'ImageComponent':
85
- return <ImageComponent key={compIndex} props={component.props as ImageComponentProps} deviceMode={deviceMode} boxHeight={getCurrentBoxHeight()} />;
86
- case 'GroupProductComponent':
87
- return <GroupProductComponent key={compIndex} props={component.props as GroupProductComponentProps} deviceMode={deviceMode} />;
88
- case 'VideoComponent':
89
- return <VideoComponent key={compIndex} props={component.props as VideoComponentProps} deviceMode={deviceMode} boxHeight={getCurrentBoxHeight()} />;
90
- case 'GroupBrandComponent':
91
- return <GroupBrandComponent key={compIndex} props={component.props as GroupBrandComponentProps} deviceMode={deviceMode} />;
92
- case 'LottieComponent':
93
- return <LottieComponent key={compIndex} props={component.props as LottieComponentProps} />;
94
- case 'CarouselComponent':
95
- return <CarouselComponent key={compIndex} props={component.props as CarouselProps} deviceMode={deviceMode} />;
96
- case 'NavigationComponent':
97
- return <NavigationComponent key={compIndex} props={component.props as NavigationProps} boxHeight={getCurrentBoxHeight()} />;
98
- case 'GroupVideoComponent':
99
- return <GroupVideoList key={compIndex} props={component.props as GroupVideoListProps} boxHeight={getCurrentBoxHeight()} />;
100
- case 'GroupCategoryComponent':
101
- return <GroupCategoryComponent key={compIndex} props={component.props as GroupCategoryComponentProps} deviceMode={deviceMode} />;
102
- case 'GroupImageComponent':
103
- return <GroupImageList key={compIndex} props={component.props as GroupImageListProps} deviceMode={deviceMode} />;
104
- case 'TabComponent':
105
- return <TabComponent key={compIndex} props={component.props as TabComponentProps} deviceMode={deviceMode} />;
106
- case 'RichTextBoxComponent':
107
- return <RichTextComponent key={compIndex} props={component.props as RichTextComponentProps} />;
108
- default:
109
- return null;
110
- }
111
- } catch (err) {
112
- console.error(`Error rendering component: ${component.name}`, err);
113
- return <div key={compIndex} style={{ color: 'red' }}>Failed to load component: {component.name}</div>;
114
- }
115
- })}
116
- </BoxComponent>
117
- ))}
118
- </RowComponent>
119
- ))}
120
- </ErrorBoundary>
121
- </div>
58
+ <ErrorBoundary>
59
+ {data.map((row: { props: any; columns: any[]; }, rowIndex: React.Key | null | undefined) => (
60
+ <RowComponent key={rowIndex} props={row.props} deviceMode={deviceMode}>
61
+ {row.columns.map((box, boxIndex) => (
62
+ <BoxComponent
63
+ key={boxIndex}
64
+ props={box.props}
65
+ deviceMode={deviceMode}
66
+ autoAdjustForImages={false}
67
+ >
68
+ {box.components.map((component: { name: string | number | bigint | boolean | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | null | undefined; props: TextProps | LinkProps | ImageComponentProps | GroupProductComponentProps | VideoComponentProps | GroupBrandComponentProps | LottieComponentProps | CarouselProps | NavigationProps | GroupVideoListProps | GroupCategoryComponentProps | GroupImageListProps | TabComponentProps | RichTextComponentProps; }, compIndex: React.Key | null | undefined) => {
69
+ const getCurrentBoxHeight = () => {
70
+ const validModes = ['web', 'mobileweb', 'mobileapp', 'tablet'] as const;
71
+ const safeDeviceMode = validModes.includes(deviceMode as any)
72
+ ? deviceMode as keyof typeof box.props.mode
73
+ : 'web';
74
+ if (component.name === 'ImageComponent') return 'auto' // add this line
75
+ return box.props.mode[safeDeviceMode]?.height || 'auto';
76
+ };
77
+
78
+ try {
79
+ switch (component.name) {
80
+ case 'TextComponent':
81
+ return <TextComponent key={compIndex} props={component.props as TextProps} />;
82
+ case 'LinkComponent':
83
+ return <LinkComponent key={compIndex} props={component.props as LinkProps} />;
84
+ case 'ImageComponent':
85
+ return <ImageComponent key={compIndex} props={component.props as ImageComponentProps} deviceMode={deviceMode} boxHeight={getCurrentBoxHeight()} />;
86
+ case 'GroupProductComponent':
87
+ {
88
+ const gpProps = component.props as GroupProductComponentProps;
89
+ return <GroupProductComponent
90
+ key={compIndex}
91
+ props={{
92
+ ...gpProps,
93
+ showsp: gpProps.showsp ?? showsp,
94
+ showdiscount: gpProps.showdiscount ?? showdiscount
95
+ }}
96
+ deviceMode={deviceMode} />;
97
+ }
98
+ case 'VideoComponent':
99
+ return <VideoComponent key={compIndex} props={component.props as VideoComponentProps} deviceMode={deviceMode} boxHeight={getCurrentBoxHeight()} />;
100
+ case 'GroupBrandComponent':
101
+ return <GroupBrandComponent key={compIndex} props={component.props as GroupBrandComponentProps} deviceMode={deviceMode} />;
102
+ case 'LottieComponent':
103
+ return <LottieComponent key={compIndex} props={component.props as LottieComponentProps} />;
104
+ case 'CarouselComponent':
105
+ return <CarouselComponent key={compIndex} props={component.props as CarouselProps} deviceMode={deviceMode} />;
106
+ case 'NavigationComponent':
107
+ return <NavigationComponent key={compIndex} props={component.props as NavigationProps} boxHeight={getCurrentBoxHeight()} />;
108
+ case 'GroupVideoComponent':
109
+ return <GroupVideoList key={compIndex} props={component.props as GroupVideoListProps} boxHeight={getCurrentBoxHeight()} />;
110
+ case 'GroupCategoryComponent':
111
+ return <GroupCategoryComponent key={compIndex} props={component.props as GroupCategoryComponentProps} deviceMode={deviceMode} />;
112
+ case 'GroupImageComponent':
113
+ return <GroupImageList key={compIndex} props={component.props as GroupImageListProps} deviceMode={deviceMode} />;
114
+ case 'TabComponent':
115
+ {
116
+ const tabProps = component.props as TabComponentProps;
117
+ return <TabComponent
118
+ key={compIndex}
119
+ props={{
120
+ ...tabProps,
121
+ showsp: tabProps.showsp ?? showsp,
122
+ showdiscount: tabProps.showdiscount ?? showdiscount
123
+ }}
124
+ deviceMode={deviceMode} />;
125
+ }
126
+ case 'RichTextBoxComponent':
127
+ return <RichTextComponent key={compIndex} props={component.props as RichTextComponentProps} />;
128
+ default:
129
+ return null;
130
+ }
131
+ } catch (err) {
132
+ console.error(`Error rendering component: ${component.name}`, err);
133
+ return <div key={compIndex} style={{ color: 'red' }}>Failed to load component: {component.name}</div>;
134
+ }
135
+ })}
136
+ </BoxComponent>
137
+ ))}
138
+ </RowComponent>
139
+ ))}
140
+ </ErrorBoundary>
122
141
  </div>
142
+ </div>
123
143
  </>
124
144
  )
125
145
  }
@@ -61,6 +61,7 @@ export interface CarouselProps {
61
61
  pagingDotVisible: boolean;
62
62
  objectFit: string;
63
63
  slides: SlidesData[] | Slide[][]; // Support both formats: SlidesData[] or nested array Slide[][]
64
+ mode?: SlideMode;
64
65
  }
65
66
 
66
67
  interface CarouselComponentMainProps {
@@ -77,20 +78,20 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
77
78
  const [isHovered, setIsHovered] = useState(false);
78
79
  const [prevButtonHovered, setPrevButtonHovered] = useState(false);
79
80
  const [nextButtonHovered, setNextButtonHovered] = useState(false);
80
-
81
+
81
82
  // Detect data structure and safely get slides with fallback
82
83
  // Check if slides[0] is an array of Slide objects (new format) or has 'all' property (old format)
83
84
  const firstSlideItem = props.slides && props.slides[0] ? props.slides[0] : null;
84
-
85
+
85
86
  // Check if it's the new nested array format (array of Slide objects)
86
- const isNestedArrayFormat = Array.isArray(firstSlideItem) &&
87
- firstSlideItem.length > 0 &&
88
- typeof firstSlideItem[0] === 'object' &&
89
- 'sl_id' in (firstSlideItem[0] as any);
90
-
87
+ const isNestedArrayFormat = Array.isArray(firstSlideItem) &&
88
+ firstSlideItem.length > 0 &&
89
+ typeof firstSlideItem[0] === 'object' &&
90
+ 'sl_id' in (firstSlideItem[0] as any);
91
+
91
92
  let slides: Slide[] = [];
92
93
  let slidesData: SlidesData | null = null;
93
-
94
+
94
95
  if (isNestedArrayFormat) {
95
96
  // New format: slides is Slide[][] - first element is an array of Slide objects
96
97
  slides = (firstSlideItem as Slide[]) || [];
@@ -102,29 +103,36 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
102
103
  // Fallback: empty array
103
104
  slides = [];
104
105
  }
105
-
106
+
106
107
  const totalSlides = slides.length;
107
108
 
108
109
  // Get current mode settings
109
110
  const getCurrentMode = () => {
110
- // If using nested array format, mode data doesn't exist, use defaults
111
- if (isNestedArrayFormat || !slidesData || !slidesData.mode) {
111
+ // 1. Check if mode is at the root (props.mode)
112
+ const rootMode = props.mode;
113
+
114
+ // 2. Check if mode is inside slides (old format - slidesData.mode)
115
+ const nestedMode = (!isNestedArrayFormat && slidesData) ? slidesData.mode : null;
116
+
117
+ const activeMode = rootMode || nestedMode;
118
+
119
+ if (!activeMode) {
112
120
  // Return default mode based on device
113
- const defaultSlidesToShow = deviceMode === 'mobileweb' || deviceMode === 'mobileapp' ? 1 :
114
- deviceMode === 'tablet' ? 2 : 1;
121
+ const defaultSlidesToShow = deviceMode === 'mobileweb' || deviceMode === 'mobileapp' ? 1 :
122
+ deviceMode === 'tablet' ? 2 : 1;
115
123
  return { slidesToShow: defaultSlidesToShow };
116
124
  }
117
-
118
- switch(deviceMode) {
125
+
126
+ switch (deviceMode) {
119
127
  case 'mobileweb':
120
- return slidesData.mode.mobileweb || { slidesToShow: 1 };
128
+ return activeMode.mobileweb || { slidesToShow: 1 };
121
129
  case 'mobileapp':
122
- return slidesData.mode.mobileapp || { slidesToShow: 1 };
130
+ return activeMode.mobileapp || { slidesToShow: 1 };
123
131
  case 'tablet':
124
- return slidesData.mode.tablet || { slidesToShow: 1 };
132
+ return activeMode.tablet || { slidesToShow: 1 };
125
133
  case 'web':
126
134
  default:
127
- return slidesData.mode.web || { slidesToShow: 1 };
135
+ return activeMode.web || { slidesToShow: 1 };
128
136
  }
129
137
  };
130
138
 
@@ -254,7 +262,7 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
254
262
  };
255
263
 
256
264
  return (
257
- <div
265
+ <div
258
266
  className="carousel-container"
259
267
  style={{
260
268
  position: 'relative',
@@ -286,7 +294,7 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
286
294
  const startIndex = groupIndex * slidesToShow;
287
295
  // Calculate how many slides are in this group (last group may have fewer)
288
296
  const slidesInGroup = Math.min(slidesToShow, totalSlides - startIndex);
289
-
297
+
290
298
  return (
291
299
  <div
292
300
  key={groupIndex}
@@ -303,7 +311,7 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
303
311
  >
304
312
  {Array.from({ length: slidesToShow }).map((_, offset) => {
305
313
  const slideIndex = startIndex + offset;
306
-
314
+
307
315
  // If this position is beyond available slides, render empty space
308
316
  if (slideIndex >= totalSlides) {
309
317
  return (
@@ -319,9 +327,9 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
319
327
  />
320
328
  );
321
329
  }
322
-
330
+
323
331
  const slide = slides[slideIndex];
324
-
332
+
325
333
  return (
326
334
  <div
327
335
  key={`${slide.sl_id}-${offset}`}
@@ -343,9 +351,9 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
343
351
  {slide.sl_type === 'video' ? (
344
352
  <video
345
353
  src={resolveAssetUrl(slide.video?.url)}
346
- style={{
347
- width: '100%',
348
- height: '100%',
354
+ style={{
355
+ width: '100%',
356
+ height: '100%',
349
357
  objectFit: props.objectFit as any,
350
358
  display: 'block',
351
359
  pointerEvents: 'none'
@@ -359,9 +367,9 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
359
367
  <img
360
368
  src={resolveAssetUrl(slide.image?.url)}
361
369
  alt={slide.image?.alt || ''}
362
- style={{
363
- width: '100%',
364
- height: '100%',
370
+ style={{
371
+ width: '100%',
372
+ height: '100%',
365
373
  objectFit: props.objectFit as any,
366
374
  display: 'block',
367
375
  pointerEvents: 'none'
@@ -470,7 +478,7 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
470
478
  const firstSlideInGroup = groupIndex * slidesToShow;
471
479
  goToSlide(firstSlideInGroup);
472
480
  };
473
-
481
+
474
482
  return (
475
483
  <button
476
484
  key={groupIndex}