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,391 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Linodeurl } from '../../const';
|
|
3
|
+
|
|
4
|
+
interface PageImage {
|
|
5
|
+
shapeImageId: string;
|
|
6
|
+
shape: string;
|
|
7
|
+
isDynamic: string;
|
|
8
|
+
url: string;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface PageId {
|
|
14
|
+
_id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
code: string;
|
|
17
|
+
image: PageImage;
|
|
18
|
+
isActive: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Channel {
|
|
22
|
+
_id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
code: string;
|
|
25
|
+
isActive: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface PageDataItem {
|
|
29
|
+
page_id: any;
|
|
30
|
+
channel: Channel;
|
|
31
|
+
}
|
|
32
|
+
interface BrandImage {
|
|
33
|
+
shapeImageId: string;
|
|
34
|
+
shape: string;
|
|
35
|
+
isDynamic: boolean | string;
|
|
36
|
+
url: string;
|
|
37
|
+
width?: number;
|
|
38
|
+
height?: number;
|
|
39
|
+
alt?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface BrandItem {
|
|
43
|
+
_id?: string;
|
|
44
|
+
code: string;
|
|
45
|
+
name: any;
|
|
46
|
+
image: BrandImage;
|
|
47
|
+
page?: string;
|
|
48
|
+
pages?: PageDataItem[];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
interface GroupBrandStatic {
|
|
52
|
+
_id: string;
|
|
53
|
+
code: string;
|
|
54
|
+
name: string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
interface GroupBrandDynamic {
|
|
58
|
+
code: string;
|
|
59
|
+
name: { all: string };
|
|
60
|
+
list: BrandItem[];
|
|
61
|
+
isActive?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
interface GroupBrandData {
|
|
65
|
+
static: GroupBrandStatic;
|
|
66
|
+
dynamic: GroupBrandDynamic;
|
|
67
|
+
showItems:BrandItem[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface HeaderTextStyle {
|
|
71
|
+
fontSize: number;
|
|
72
|
+
fontColor: string;
|
|
73
|
+
isBold: boolean;
|
|
74
|
+
isItalic: boolean;
|
|
75
|
+
isUnderline: boolean;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface DeviceBooleanProps {
|
|
79
|
+
web: boolean;
|
|
80
|
+
mobileweb: boolean;
|
|
81
|
+
mobileapp: boolean;
|
|
82
|
+
tablet: boolean;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
interface DeviceLayoutProps {
|
|
86
|
+
web: string;
|
|
87
|
+
mobileweb: string;
|
|
88
|
+
mobileapp: string;
|
|
89
|
+
tablet: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface GroupBrandComponentProps {
|
|
93
|
+
headerText: any;
|
|
94
|
+
type: string;
|
|
95
|
+
groupbrand: GroupBrandData;
|
|
96
|
+
showItems?:BrandItem[];
|
|
97
|
+
selectedBrands?: BrandItem[];
|
|
98
|
+
items?: BrandItem[];
|
|
99
|
+
cardColor: string;
|
|
100
|
+
showProductName: DeviceBooleanProps;
|
|
101
|
+
headerTextStyle: HeaderTextStyle;
|
|
102
|
+
layout: DeviceLayoutProps;
|
|
103
|
+
style: DeviceLayoutProps;
|
|
104
|
+
showHeader: DeviceBooleanProps;
|
|
105
|
+
isHorizontalScroll: DeviceBooleanProps;
|
|
106
|
+
headerBackground: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
interface GroupBrandComponentMainProps {
|
|
110
|
+
props: GroupBrandComponentProps;
|
|
111
|
+
deviceMode?: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const GroupBrandComponent: React.FC<GroupBrandComponentMainProps> = ({ props, deviceMode = 'web' }) => {
|
|
115
|
+
const getCurrentBooleanProp = (prop?: DeviceBooleanProps) => {
|
|
116
|
+
if (!prop) return false;
|
|
117
|
+
switch (deviceMode) {
|
|
118
|
+
case 'mobileweb': return !!prop.mobileweb;
|
|
119
|
+
case 'mobileapp': return !!prop.mobileapp;
|
|
120
|
+
case 'tablet': return !!prop.tablet;
|
|
121
|
+
case 'web':
|
|
122
|
+
default: return !!prop.web;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
const getCurrentLayout = () => {
|
|
127
|
+
// Safely fall back to web, then to 'NONE' if the specific layout is missing
|
|
128
|
+
if (!props.layout) return 'NONE';
|
|
129
|
+
switch (deviceMode) {
|
|
130
|
+
case 'mobileweb': return props.layout.mobileweb || 'NONE';
|
|
131
|
+
case 'mobileapp': return props.layout.mobileapp || 'NONE';
|
|
132
|
+
case 'tablet': return props.layout.tablet || 'NONE';
|
|
133
|
+
case 'web':
|
|
134
|
+
default: return props.layout.web || 'NONE';
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
const showHeader = getCurrentBooleanProp(props.showHeader);
|
|
141
|
+
const showBrandName = getCurrentBooleanProp(props.showProductName);
|
|
142
|
+
const isHorizontalScroll = getCurrentBooleanProp(props.isHorizontalScroll);
|
|
143
|
+
const currentLayout = getCurrentLayout();
|
|
144
|
+
const currentStyle = 'NONE'
|
|
145
|
+
|
|
146
|
+
const getBrands = (): BrandItem[] => {
|
|
147
|
+
if (props.groupbrand?.showItems) {
|
|
148
|
+
// if (props.items && props.items.length) return props.items;
|
|
149
|
+
if (props.groupbrand?.showItems?.length) return props.groupbrand?.showItems;
|
|
150
|
+
}
|
|
151
|
+
// if (props.selectedBrands && props.selectedBrands.length) return props.selectedBrands;
|
|
152
|
+
return [];
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const brands = getBrands();
|
|
156
|
+
|
|
157
|
+
// Carousel navigation buttons (layout NONE)
|
|
158
|
+
const scrollLeft = () => {
|
|
159
|
+
const carousel = document.querySelector('.groupBrandCarousel');
|
|
160
|
+
if (carousel) {
|
|
161
|
+
(carousel as HTMLElement).scrollBy({ left: -200, behavior: 'smooth' });
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const scrollRight = () => {
|
|
166
|
+
const carousel = document.querySelector('.groupBrandCarousel');
|
|
167
|
+
if (carousel) {
|
|
168
|
+
(carousel as HTMLElement).scrollBy({ left: 200, behavior: 'smooth' });
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const getImageUrl = (url: string) => {
|
|
173
|
+
if (!url) return '';
|
|
174
|
+
if (url.startsWith('http://') || url.startsWith('https://')) return url;
|
|
175
|
+
return `${Linodeurl}${url}`;
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const buildBrandHref = (item: BrandItem): string | null => {
|
|
179
|
+
console.log(item);
|
|
180
|
+
|
|
181
|
+
// Check if item has pages and at least one page exists
|
|
182
|
+
if (item.pages && item.pages.length > 0) {
|
|
183
|
+
const firstPage = item.pages[0];
|
|
184
|
+
|
|
185
|
+
// Check if the page is active
|
|
186
|
+
console.log(firstPage.page_id?._id);
|
|
187
|
+
// If page is active, use the brand page format
|
|
188
|
+
return `/page/${encodeURIComponent(firstPage.page_id)}`;
|
|
189
|
+
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Fallback if no pages exist
|
|
193
|
+
return null;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const Card = ({ item, large = false }: { item: BrandItem; large?: boolean }) => (
|
|
197
|
+
<a
|
|
198
|
+
href={buildBrandHref(item)|| undefined}
|
|
199
|
+
style={{ textDecoration: 'none', color: 'inherit' }}
|
|
200
|
+
>
|
|
201
|
+
<div
|
|
202
|
+
className="brandCard"
|
|
203
|
+
style={{
|
|
204
|
+
height: 'auto',
|
|
205
|
+
borderRadius: '8px',
|
|
206
|
+
overflow: 'hidden',
|
|
207
|
+
border: '1px solid #eee',
|
|
208
|
+
backgroundColor: '#fff',
|
|
209
|
+
display: 'flex',
|
|
210
|
+
flexDirection: 'column',
|
|
211
|
+
alignItems: 'center',
|
|
212
|
+
justifyContent: 'center',
|
|
213
|
+
padding: large ? '16px' : '12px',
|
|
214
|
+
boxShadow: '0 2px 4px rgba(0,0,0,0.1)',
|
|
215
|
+
transition: 'transform 0.2s ease',
|
|
216
|
+
cursor: 'pointer'
|
|
217
|
+
}}
|
|
218
|
+
onMouseOver={(e) => {
|
|
219
|
+
(e.currentTarget as HTMLDivElement).style.transform = 'translateY(-2px)';
|
|
220
|
+
(e.currentTarget as HTMLDivElement).style.boxShadow = '0 4px 8px rgba(0,0,0,0.15)';
|
|
221
|
+
}}
|
|
222
|
+
onMouseOut={(e) => {
|
|
223
|
+
(e.currentTarget as HTMLDivElement).style.transform = 'translateY(0)';
|
|
224
|
+
(e.currentTarget as HTMLDivElement).style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
|
|
225
|
+
}}
|
|
226
|
+
>
|
|
227
|
+
<div style={{ height: large ? '160px' : '120px', width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: large ? '12px' : '8px' }}>
|
|
228
|
+
<img src={getImageUrl(item.image.url)} alt={item.image.alt || ''} style={{ width: '100%', height: '100%', objectFit: 'contain' }} />
|
|
229
|
+
</div>
|
|
230
|
+
{showBrandName && (
|
|
231
|
+
<div style={{ textAlign: 'center', fontSize: large ? '16px' : '14px', fontWeight: large ? 600 as any : 500 as any, color: '#333', lineHeight: '1.4', height: large ? 'auto' : '40px', overflow: 'hidden', display: large ? 'block' : '-webkit-box', WebkitLineClamp: large ? undefined as any : 2, WebkitBoxOrient: 'vertical' as any }}>
|
|
232
|
+
{item.name}
|
|
233
|
+
</div>
|
|
234
|
+
)}
|
|
235
|
+
</div>
|
|
236
|
+
</a>
|
|
237
|
+
);
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
<div
|
|
241
|
+
style={{
|
|
242
|
+
border: '1px solid #e1e1e1',
|
|
243
|
+
width: '100%',
|
|
244
|
+
maxWidth: '100%',
|
|
245
|
+
borderRadius: '0px',
|
|
246
|
+
minHeight: '100px',
|
|
247
|
+
position: 'relative',
|
|
248
|
+
overflow: 'hidden',
|
|
249
|
+
marginBottom: '20px',
|
|
250
|
+
marginTop: '0px'
|
|
251
|
+
}}
|
|
252
|
+
className='GroupBrandComponent'
|
|
253
|
+
>
|
|
254
|
+
{showHeader && (
|
|
255
|
+
<div
|
|
256
|
+
className="groupBrandHeader"
|
|
257
|
+
style={{
|
|
258
|
+
backgroundColor: props.headerBackground,
|
|
259
|
+
padding: '12px 16px',
|
|
260
|
+
borderRadius: '0px',
|
|
261
|
+
marginBottom: '4px',
|
|
262
|
+
display: 'flex',
|
|
263
|
+
alignItems: 'center',
|
|
264
|
+
justifyContent: 'space-between',
|
|
265
|
+
flexWrap: 'wrap',
|
|
266
|
+
gap: '12px',
|
|
267
|
+
}}
|
|
268
|
+
>
|
|
269
|
+
<p style={{
|
|
270
|
+
color: props.headerTextStyle.fontColor,
|
|
271
|
+
fontSize: `${props.headerTextStyle.fontSize}px`,
|
|
272
|
+
fontWeight: props.headerTextStyle.isBold ? 'bold' : 'normal',
|
|
273
|
+
fontStyle: props.headerTextStyle.isItalic ? 'italic' : 'normal',
|
|
274
|
+
textDecoration: props.headerTextStyle.isUnderline ? 'underline' : 'none',
|
|
275
|
+
margin: 0
|
|
276
|
+
}}>
|
|
277
|
+
{props.headerText || 'Brands'}
|
|
278
|
+
</p>
|
|
279
|
+
|
|
280
|
+
{currentLayout === 'NONE' && brands.length > 0 && (
|
|
281
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
282
|
+
<button
|
|
283
|
+
onClick={scrollLeft}
|
|
284
|
+
style={{
|
|
285
|
+
width: '32px',
|
|
286
|
+
height: '32px',
|
|
287
|
+
borderRadius: '50%',
|
|
288
|
+
border: '1px solid #ddd',
|
|
289
|
+
backgroundColor: '#fff',
|
|
290
|
+
cursor: 'pointer',
|
|
291
|
+
display: 'flex',
|
|
292
|
+
alignItems: 'center',
|
|
293
|
+
justifyContent: 'center',
|
|
294
|
+
fontSize: '16px',
|
|
295
|
+
fontWeight: 'bold'
|
|
296
|
+
}}
|
|
297
|
+
onMouseOver={(e) => { e.currentTarget.style.backgroundColor = '#f8f9fa'; }}
|
|
298
|
+
onMouseOut={(e) => { e.currentTarget.style.backgroundColor = '#fff'; }}
|
|
299
|
+
>
|
|
300
|
+
‹
|
|
301
|
+
</button>
|
|
302
|
+
<button
|
|
303
|
+
onClick={scrollRight}
|
|
304
|
+
style={{
|
|
305
|
+
width: '32px',
|
|
306
|
+
height: '32px',
|
|
307
|
+
borderRadius: '50%',
|
|
308
|
+
border: '1px solid #ddd',
|
|
309
|
+
backgroundColor: '#fff',
|
|
310
|
+
cursor: 'pointer',
|
|
311
|
+
display: 'flex',
|
|
312
|
+
alignItems: 'center',
|
|
313
|
+
justifyContent: 'center',
|
|
314
|
+
fontSize: '16px',
|
|
315
|
+
fontWeight: 'bold'
|
|
316
|
+
}}
|
|
317
|
+
onMouseOver={(e) => { e.currentTarget.style.backgroundColor = '#f8f9fa'; }}
|
|
318
|
+
onMouseOut={(e) => { e.currentTarget.style.backgroundColor = '#fff'; }}
|
|
319
|
+
>
|
|
320
|
+
›
|
|
321
|
+
</button>
|
|
322
|
+
</div>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
)}
|
|
326
|
+
|
|
327
|
+
<div
|
|
328
|
+
style={{
|
|
329
|
+
display: currentLayout === 'NONE' ? 'flex' : 'block',
|
|
330
|
+
overflowX: currentLayout === 'NONE' ? (isHorizontalScroll ? 'auto' : 'hidden') : 'visible',
|
|
331
|
+
gap: currentLayout === 'NONE' ? '12px' : '0',
|
|
332
|
+
padding: '12px',
|
|
333
|
+
scrollBehavior: 'smooth',
|
|
334
|
+
backgroundColor: props.cardColor || '#fff',
|
|
335
|
+
scrollbarWidth: 'thin',
|
|
336
|
+
borderRadius: '8px',
|
|
337
|
+
position: 'relative',
|
|
338
|
+
scrollbarColor: '#c1c1c1 transparent'
|
|
339
|
+
}}
|
|
340
|
+
className="groupBrandCarousel"
|
|
341
|
+
>
|
|
342
|
+
{brands.length > 0 ? (
|
|
343
|
+
currentLayout === 'NONE' ? (
|
|
344
|
+
brands.map((brand) => (
|
|
345
|
+
currentStyle === 'NONE' ? (
|
|
346
|
+
<div key={brand.code} style={{ minWidth: '150px' }}>
|
|
347
|
+
<Card item={brand} />
|
|
348
|
+
</div>
|
|
349
|
+
) : (
|
|
350
|
+
<div key={brand.code} style={{ minWidth: '150px' }}>
|
|
351
|
+
<Card item={brand} />
|
|
352
|
+
</div>
|
|
353
|
+
)
|
|
354
|
+
))
|
|
355
|
+
) : currentLayout === 'SMALL' ? (
|
|
356
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '16px', padding: '8px' }}>
|
|
357
|
+
{brands.map((brand) => (
|
|
358
|
+
<Card key={brand.code} item={brand} />
|
|
359
|
+
))}
|
|
360
|
+
</div>
|
|
361
|
+
) : currentLayout === 'MEDIUM' ? (
|
|
362
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '16px', padding: '8px' }}>
|
|
363
|
+
{brands.map((brand) => (
|
|
364
|
+
<Card key={brand.code} item={brand} />
|
|
365
|
+
))}
|
|
366
|
+
</div>
|
|
367
|
+
) : currentLayout === 'MEDIUM_THREE' ? (
|
|
368
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '8px' }}>
|
|
369
|
+
{brands.length > 0 && (
|
|
370
|
+
<Card item={brands[0]} large />
|
|
371
|
+
)}
|
|
372
|
+
{brands.length > 1 && (
|
|
373
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '16px' }}>
|
|
374
|
+
{brands.slice(1).map((brand) => (
|
|
375
|
+
<Card key={brand.code} item={brand} />
|
|
376
|
+
))}
|
|
377
|
+
</div>
|
|
378
|
+
)}
|
|
379
|
+
</div>
|
|
380
|
+
) : null
|
|
381
|
+
) : (
|
|
382
|
+
<div style={{ textAlign: 'center', color: '#666', padding: '40px', width: '100%', border: '2px dashed #ddd', borderRadius: '8px', backgroundColor: '#f9f9f9' }}>
|
|
383
|
+
<p>No brands available.</p>
|
|
384
|
+
</div>
|
|
385
|
+
)}
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
);
|
|
389
|
+
};
|
|
390
|
+
|
|
391
|
+
export default GroupBrandComponent
|