tee3apps-cms-sdk-react 0.0.1
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/.env +11 -0
- package/README.md +255 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +33 -0
- package/rollup.config.js +43 -0
- package/src/Components/BoxRenderer.tsx +108 -0
- package/src/Components/ComponentRenderer.tsx +29 -0
- package/src/Components/ImageComponent.tsx +68 -0
- package/src/Components/RowComponent.tsx +66 -0
- package/src/Components/TextComponent.tsx +47 -0
- package/src/ErrorBoundary.tsx +35 -0
- package/src/Page.tsx +124 -0
- package/src/PageComponents/BoxComponent.tsx +397 -0
- package/src/PageComponents/RowComponent.tsx +113 -0
- package/src/PageComponents/Visual-Components/CarouselComponent.tsx +366 -0
- package/src/PageComponents/Visual-Components/GroupBrandComponent.tsx +391 -0
- package/src/PageComponents/Visual-Components/GroupCategoryComponent.tsx +425 -0
- package/src/PageComponents/Visual-Components/GroupImageList.tsx +669 -0
- package/src/PageComponents/Visual-Components/GroupProductComponent.tsx +671 -0
- package/src/PageComponents/Visual-Components/GroupVideoList.tsx +590 -0
- package/src/PageComponents/Visual-Components/ImageComponent.tsx +163 -0
- package/src/PageComponents/Visual-Components/LinkComponent.tsx +68 -0
- package/src/PageComponents/Visual-Components/LottieComponent.tsx +213 -0
- package/src/PageComponents/Visual-Components/NavigationComponent.tsx +178 -0
- package/src/PageComponents/Visual-Components/Styles/ProductListViewOne.tsx +102 -0
- package/src/PageComponents/Visual-Components/Styles/ProductListViewTwo.tsx +104 -0
- package/src/PageComponents/Visual-Components/Styles/product-list-view-one.css +166 -0
- package/src/PageComponents/Visual-Components/Styles/product-list-view-two.css +182 -0
- package/src/PageComponents/Visual-Components/TabComponent.tsx +1169 -0
- package/src/PageComponents/Visual-Components/TextComponent.tsx +114 -0
- package/src/PageComponents/Visual-Components/VideoComponent.tsx +191 -0
- package/src/PageComponents/Visual-Components/tab.css +697 -0
- package/src/common.interface.ts +216 -0
- package/src/const.ts +6 -0
- package/src/env.d.ts +15 -0
- package/src/index.css +82 -0
- package/src/index.ts +2 -0
- package/src/types.ts +234 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ComponentProps } from '../../types';
|
|
3
|
+
|
|
4
|
+
const TextComponent: React.FC<{ props: ComponentProps }> = ({ props }) => {
|
|
5
|
+
const { text, style } = props;
|
|
6
|
+
|
|
7
|
+
const tagName = style?.headingTag ?? 'p';
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const textStyle = {
|
|
12
|
+
fontSize: style?.fontSize ? `${style.fontSize}px` : '16px',
|
|
13
|
+
fontWeight: style?.fontStyle?.isBold ? 'bold' : 'normal',
|
|
14
|
+
fontStyle: style?.fontStyle?.isItalic ? 'italic' : 'normal',
|
|
15
|
+
textDecoration: style?.fontStyle?.isUnderLine ? 'underline' : 'none',
|
|
16
|
+
textDecorationLine: style?.fontStyle?.isStrikeThrough ? 'line-through' : 'none',
|
|
17
|
+
color: style?.fontColor || '#000',
|
|
18
|
+
textAlign: style?.textAlign || 'left',
|
|
19
|
+
fontFamily: style?.fontFamily || 'inherit',
|
|
20
|
+
margin: 5,
|
|
21
|
+
wordWrap: "break-word",
|
|
22
|
+
overflowWrap: "break-word",
|
|
23
|
+
maxWidth: "100%",
|
|
24
|
+
whiteSpace: "normal",
|
|
25
|
+
width: "100%",
|
|
26
|
+
boxSizing: "border-box",
|
|
27
|
+
wordBreak: "break-word",
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
// ✅ Build the dynamic link URL
|
|
31
|
+
const buildLink = (): string | null => {
|
|
32
|
+
const linkData = props;
|
|
33
|
+
|
|
34
|
+
switch (linkData.linktype) {
|
|
35
|
+
case 'NONE':
|
|
36
|
+
return null;
|
|
37
|
+
case 'EXTERNAL_LINK':
|
|
38
|
+
case 'EXTERNAL':
|
|
39
|
+
return linkData.link?.url || null;
|
|
40
|
+
case 'PRODUCT':
|
|
41
|
+
const pdType = linkData.product?.pd_type;
|
|
42
|
+
const code = linkData.product?.pd_id?.code || linkData.product?.code || linkData.product?.product_data?.code;
|
|
43
|
+
|
|
44
|
+
if (!code) return null;
|
|
45
|
+
|
|
46
|
+
return pdType === 'VARIANT'
|
|
47
|
+
? `/variant/${code}`
|
|
48
|
+
: `model/${code}`;
|
|
49
|
+
case 'TAG':
|
|
50
|
+
return `/tag/${linkData.tag?.code}`;
|
|
51
|
+
case 'PAGE':
|
|
52
|
+
return `/page/${linkData.page?._id}?type=${linkData.page?.pg_type}`;
|
|
53
|
+
default:
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const url = buildLink();
|
|
59
|
+
|
|
60
|
+
const textElement = React.createElement(
|
|
61
|
+
tagName,
|
|
62
|
+
{ style: textStyle },
|
|
63
|
+
text
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
// ✅ Wrap text in anchor tag if link is present
|
|
67
|
+
if (url) {
|
|
68
|
+
return (
|
|
69
|
+
<div style={{
|
|
70
|
+
display: "block",
|
|
71
|
+
width: "100%",
|
|
72
|
+
maxWidth: "100%",
|
|
73
|
+
wordWrap: "break-word",
|
|
74
|
+
overflowWrap: "break-word",
|
|
75
|
+
boxSizing: "border-box",
|
|
76
|
+
}}>
|
|
77
|
+
<a
|
|
78
|
+
href={url}
|
|
79
|
+
target={props?.linktype=='EXTERNAL' ? props?.link?.target :'_self'}
|
|
80
|
+
style={{
|
|
81
|
+
textDecoration: 'none',
|
|
82
|
+
display: "inline-block",
|
|
83
|
+
width: "100%",
|
|
84
|
+
maxWidth: "100%",
|
|
85
|
+
boxSizing: "border-box",
|
|
86
|
+
wordWrap: "break-word",
|
|
87
|
+
overflowWrap: "break-word",
|
|
88
|
+
whiteSpace: "normal",
|
|
89
|
+
wordBreak: "break-word",
|
|
90
|
+
color: style?.fontColor || 'inherit',
|
|
91
|
+
}}
|
|
92
|
+
>
|
|
93
|
+
{textElement}
|
|
94
|
+
</a>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div style={{
|
|
101
|
+
display: "block",
|
|
102
|
+
width: "100%",
|
|
103
|
+
maxWidth: "100%",
|
|
104
|
+
wordWrap: "break-word",
|
|
105
|
+
overflowWrap: "break-word",
|
|
106
|
+
boxSizing: "border-box",
|
|
107
|
+
padding: '20px'
|
|
108
|
+
}}>
|
|
109
|
+
{textElement}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export default TextComponent;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import '../../../src/index.css';
|
|
3
|
+
import { Linodeurl } from '../../const';
|
|
4
|
+
|
|
5
|
+
interface VideoData {
|
|
6
|
+
url: string;
|
|
7
|
+
type: 'Youtube' | 'Vimeo' | 'Dailymotion' | 'Video';
|
|
8
|
+
controls?: boolean;
|
|
9
|
+
loop?: boolean;
|
|
10
|
+
alt?: string;
|
|
11
|
+
thumbnail?: Record<string, unknown>;
|
|
12
|
+
autoplay?: boolean;
|
|
13
|
+
muted?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface VideoModeProps {
|
|
17
|
+
borderRadius: number;
|
|
18
|
+
height: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface VideoComponentProps {
|
|
22
|
+
videos: VideoData;
|
|
23
|
+
mode: {
|
|
24
|
+
web: VideoModeProps;
|
|
25
|
+
mobileweb: VideoModeProps;
|
|
26
|
+
mobileapp: VideoModeProps;
|
|
27
|
+
tablet: VideoModeProps;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface VideoComponentMainProps {
|
|
32
|
+
props: VideoComponentProps;
|
|
33
|
+
deviceMode?: string;
|
|
34
|
+
boxHeight?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const extractYouTubeId = (url: string): string | null => {
|
|
38
|
+
try {
|
|
39
|
+
const parsed = new URL(url);
|
|
40
|
+
if (parsed.hostname.includes('youtu.be')) {
|
|
41
|
+
return parsed.pathname.replace('/', '') || null;
|
|
42
|
+
}
|
|
43
|
+
if (parsed.hostname.includes('youtube.com')) {
|
|
44
|
+
if (parsed.pathname.startsWith('/watch')) {
|
|
45
|
+
return parsed.searchParams.get('v');
|
|
46
|
+
}
|
|
47
|
+
if (parsed.pathname.startsWith('/embed/')) {
|
|
48
|
+
return parsed.pathname.split('/embed/')[1] || null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
} catch {}
|
|
52
|
+
return null;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const extractVimeoId = (url: string): string | null => {
|
|
56
|
+
try {
|
|
57
|
+
const parsed = new URL(url);
|
|
58
|
+
if (parsed.hostname.includes('vimeo.com')) {
|
|
59
|
+
const parts = parsed.pathname.split('/').filter(Boolean);
|
|
60
|
+
if (parts[0] === 'video') return parts[1] || null;
|
|
61
|
+
return parts[0] || null;
|
|
62
|
+
}
|
|
63
|
+
if (parsed.hostname.includes('player.vimeo.com')) {
|
|
64
|
+
const parts = parsed.pathname.split('/').filter(Boolean);
|
|
65
|
+
return parts[1] || null;
|
|
66
|
+
}
|
|
67
|
+
} catch {}
|
|
68
|
+
return null;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const extractDailymotionId = (url: string): string | null => {
|
|
72
|
+
try {
|
|
73
|
+
const parsed = new URL(url);
|
|
74
|
+
if (parsed.hostname.includes('dailymotion.com')) {
|
|
75
|
+
const parts = parsed.pathname.split('/').filter(Boolean);
|
|
76
|
+
if (parts[0] === 'video') return parts[1] || null;
|
|
77
|
+
}
|
|
78
|
+
if (parsed.hostname.includes('dai.ly')) {
|
|
79
|
+
return parsed.pathname.replace('/', '') || null;
|
|
80
|
+
}
|
|
81
|
+
} catch {}
|
|
82
|
+
return null;
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const VideoComponent: React.FC<VideoComponentMainProps> = ({
|
|
86
|
+
props,
|
|
87
|
+
deviceMode = 'web',
|
|
88
|
+
boxHeight = '280px',
|
|
89
|
+
}) => {
|
|
90
|
+
const getCurrentMode = () => {
|
|
91
|
+
switch (deviceMode) {
|
|
92
|
+
case 'mobileweb':
|
|
93
|
+
return props.mode.mobileweb;
|
|
94
|
+
case 'mobileapp':
|
|
95
|
+
return props.mode.mobileapp;
|
|
96
|
+
case 'tablet':
|
|
97
|
+
return props.mode.tablet;
|
|
98
|
+
case 'web':
|
|
99
|
+
default:
|
|
100
|
+
return props.mode.web;
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const currentMode = getCurrentMode();
|
|
105
|
+
const video = props.videos;
|
|
106
|
+
|
|
107
|
+
const containerHeight = boxHeight;
|
|
108
|
+
|
|
109
|
+
const renderPlayer = () => {
|
|
110
|
+
const commonStyle: React.CSSProperties = {
|
|
111
|
+
width: '100%',
|
|
112
|
+
height: '100%',
|
|
113
|
+
border: 0,
|
|
114
|
+
borderRadius: `${currentMode.borderRadius}px`,
|
|
115
|
+
objectFit: 'contain',
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (video.type === 'Youtube') {
|
|
119
|
+
const id = extractYouTubeId(video.url);
|
|
120
|
+
const src = id ? `https://www.youtube.com/embed/${id}` : video.url;
|
|
121
|
+
return (
|
|
122
|
+
<iframe
|
|
123
|
+
title={video.alt || 'YouTube video'}
|
|
124
|
+
src={src}
|
|
125
|
+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
|
126
|
+
allowFullScreen
|
|
127
|
+
style={commonStyle}
|
|
128
|
+
/>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (video.type === 'Vimeo') {
|
|
133
|
+
const id = extractVimeoId(video.url);
|
|
134
|
+
const src = id ? `https://player.vimeo.com/video/${id}` : video.url;
|
|
135
|
+
return (
|
|
136
|
+
<iframe
|
|
137
|
+
title={video.alt || 'Vimeo video'}
|
|
138
|
+
src={src}
|
|
139
|
+
allow="autoplay; fullscreen; picture-in-picture"
|
|
140
|
+
allowFullScreen
|
|
141
|
+
style={commonStyle}
|
|
142
|
+
/>
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (video.type === 'Dailymotion') {
|
|
147
|
+
const id = extractDailymotionId(video.url);
|
|
148
|
+
const src = id ? `https://www.dailymotion.com/embed/video/${id}` : video.url;
|
|
149
|
+
return (
|
|
150
|
+
<iframe
|
|
151
|
+
title={video.alt || 'Dailymotion video'}
|
|
152
|
+
src={src}
|
|
153
|
+
allow="autoplay; fullscreen; picture-in-picture"
|
|
154
|
+
allowFullScreen
|
|
155
|
+
style={commonStyle}
|
|
156
|
+
/>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Default: normal video
|
|
161
|
+
return (
|
|
162
|
+
<video
|
|
163
|
+
autoPlay={video.autoplay !== false}
|
|
164
|
+
muted={video.muted !== false}
|
|
165
|
+
playsInline
|
|
166
|
+
controls={video.controls !== false}
|
|
167
|
+
loop={video.loop === true}
|
|
168
|
+
style={{ width: '100%', height: '100%', borderRadius: `${currentMode.borderRadius}px` }}
|
|
169
|
+
poster={typeof video.thumbnail === 'string' ? video.thumbnail : undefined}
|
|
170
|
+
>
|
|
171
|
+
<source src={`${Linodeurl}${video.url}`} />
|
|
172
|
+
</video>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div
|
|
178
|
+
className="image-box"
|
|
179
|
+
style={{
|
|
180
|
+
borderRadius: `${currentMode.borderRadius}px`,
|
|
181
|
+
height: containerHeight,
|
|
182
|
+
objectFit: 'contain',
|
|
183
|
+
|
|
184
|
+
}}
|
|
185
|
+
>
|
|
186
|
+
{renderPlayer()}
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
export default VideoComponent;
|