🆕 添加卡片标签组件,优惠券组件,需要自定义接入

This commit is contained in:
xujiang 2021-01-02 14:04:19 +08:00
parent 28a3a5e53a
commit 1448e2b689
25 changed files with 1154 additions and 0 deletions

BIN
src/assets/cardLabel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
src/assets/cunpos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,31 @@
.topArea {
padding: 10px;
display: flex;
background: linear-gradient(45deg, rgba(212, 176, 11, 1), rgba(240, 123, 123, 1));
align-items: center;
.leftBox {
max-width: 72px;
max-height: 72px;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: contain;
}
}
.rightBox {
margin-left: 6px;
.title {
display: inline-block;
border-radius: 10px;
font-size: 12px;
}
.desc {
margin-top: 3px;
font-size: 12px;
transform: scale(0.8);
transform-origin: left;
color: #fff;
}
}
}

View File

@ -0,0 +1,52 @@
import React, { memo } from 'react';
import { IZLConfig } from './schema';
import logo from '@/assets/cardLabel.png';
import styles from './index.less';
interface IProps extends IZLConfig {
isTpl?: boolean;
}
const Coupons = memo((props: IProps) => {
const { title, desc, link, frontColor, titColor, round, imgUrl, bgColor, isTpl } = props;
const toLink = () => {
if (link && window.location.href.indexOf('editor') < 0) {
window.location.href = link;
}
};
return isTpl ? (
<div>
<img style={{ width: '100%' }} src={logo} alt=""></img>
</div>
) : (
<div
style={{
maxWidth: 'calc(100% - 8px)',
borderRadius: round + 'px',
margin: '4px auto',
overflow: 'hidden',
boxShadow: '0 0 6px rgba(0,0,0, .1)',
}}
>
<div
className={styles.topArea}
style={{ backgroundImage: `linear-gradient(45deg, ${frontColor}, ${bgColor})` }}
onClick={toLink}
>
<div className={styles.leftBox}>
<img src={imgUrl && imgUrl[0].url} alt="" />
</div>
{title && (
<div className={styles.rightBox}>
<div className={styles.title} style={{ color: titColor }}>
{title}
</div>
<div className={styles.desc}>{desc}</div>
</div>
)}
</div>
</div>
);
});
export default Coupons;

View File

@ -0,0 +1,102 @@
import {
IColorConfigType,
INumberConfigType,
ITextConfigType,
ITextAreaConfigType,
IUploadConfigType,
IRichTextConfigType,
TColorDefaultType,
TNumberDefaultType,
TTextDefaultType,
TUploadDefaultType,
} from '@/core/FormComponents/types';
import { serverUrl } from '@/utils/tool';
export type TZLEditData = Array<
| IUploadConfigType
| ITextConfigType
| IColorConfigType
| INumberConfigType
| ITextAreaConfigType
| IRichTextConfigType
>;
export interface IZLConfig {
imgUrl: TUploadDefaultType;
title: TTextDefaultType;
titColor: TColorDefaultType;
desc: TTextDefaultType;
round: TNumberDefaultType;
bgColor: TColorDefaultType;
frontColor: TColorDefaultType;
link: TTextDefaultType;
}
export interface ICardSchema {
editData: TZLEditData;
config: IZLConfig;
}
const CardLabel: ICardSchema = {
editData: [
{
key: 'imgUrl',
name: '图片',
type: 'Upload',
},
{
key: 'title',
name: '标题',
type: 'Text',
},
{
key: 'titColor',
name: '标题颜色',
type: 'Color',
},
{
key: 'desc',
name: '描述',
type: 'Text',
},
{
key: 'round',
name: '圆角',
type: 'Number',
},
{
key: 'bgColor',
name: '背景色',
type: 'Color',
},
{
key: 'frontColor',
name: '前景色',
type: 'Color',
},
{
key: 'link',
name: '跳转链接',
type: 'Text',
},
],
config: {
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/1_1740c6fbcd9.png`,
},
],
bgColor: 'rgba(168,11,212,1)',
round: 4,
link: 'http://h5.dooring.cn',
title: '贵宾专享',
titColor: 'rgba(255,255,255,1)',
desc: '满199减100',
frontColor: 'rgba(240,123,123,1)',
},
};
export default CardLabel;

View File

@ -0,0 +1,6 @@
const template = {
type: 'CardLabel',
h: 40,
displayName: '商品标签',
};
export default template;

View File

@ -0,0 +1,33 @@
.topArea {
padding: 16px;
display: flex;
background-color: rgb(228, 162, 22);
.leftBox {
color: #fff;
span {
font-size: 30px;
}
}
.rightBox {
margin-left: auto;
.label {
display: inline-block;
padding: 2px 8px;
border-radius: 10px;
font-size: 14px;
color: rgb(228, 162, 22);
background-color: #fff;
}
.time {
margin-top: 3px;
font-size: 12px;
color: #fff;
}
}
}
.ft {
padding-left: 16px;
padding-right: 16px;
line-height: 2;
color: rgb(117, 116, 115);
}

View File

@ -0,0 +1,47 @@
import React, { memo } from 'react';
import { IZLConfig } from './schema';
import logo from '@/assets/cunpos.png';
import styles from './index.less';
interface IProps extends IZLConfig {
isTpl?: boolean;
}
const Coupons = memo((props: IProps) => {
const { money, ifText, desc, dealTime, link, bgColor, isTpl } = props;
const toLink = () => {
if (link && window.location.href.indexOf('editor') < 0) {
window.location.href = link;
}
};
return isTpl ? (
<div>
<img style={{ width: '100%' }} src={logo} alt=""></img>
</div>
) : (
<div
style={{
width: 'calc(100% - 32px)',
borderRadius: '6px',
margin: '16px auto',
overflow: 'hidden',
boxShadow: '0 0 6px rgba(0,0,0, .1)',
}}
>
<div className={styles.topArea} style={{ backgroundColor: bgColor }} onClick={toLink}>
<div className={styles.leftBox}>
<span>{money}</span>
</div>
<div className={styles.rightBox}>
<div className={styles.label} style={{ color: bgColor }}>
{ifText}
</div>
<div className={styles.time}>{dealTime}</div>
</div>
</div>
<div className={styles.ft}>{desc}</div>
</div>
);
});
export default Coupons;

View File

@ -0,0 +1,83 @@
import {
IColorConfigType,
INumberConfigType,
ITextConfigType,
ITextAreaConfigType,
IUploadConfigType,
IRichTextConfigType,
TColorDefaultType,
TNumberDefaultType,
TTextDefaultType,
TUploadDefaultType,
TTextAreaDefaultType,
TRichTextDefaultType,
} from '@/core/FormComponents/types';
import { serverUrl } from '@/utils/tool';
export type TZLEditData = Array<
| IUploadConfigType
| ITextConfigType
| IColorConfigType
| INumberConfigType
| ITextAreaConfigType
| IRichTextConfigType
>;
export interface IZLConfig {
bgColor: TColorDefaultType;
money: TNumberDefaultType;
link: TTextDefaultType;
ifText: TTextDefaultType;
dealTime: TTextAreaDefaultType;
desc: TTextAreaDefaultType;
}
export interface ICardSchema {
editData: TZLEditData;
config: IZLConfig;
}
const ZhuanLan: ICardSchema = {
editData: [
{
key: 'bgColor',
name: '背景颜色',
type: 'Color',
},
{
key: 'money',
name: '优惠金额',
type: 'Number',
},
{
key: 'ifText',
name: '优惠条件',
type: 'Text',
},
{
key: 'dealTime',
name: '有效期',
type: 'TextArea',
},
{
key: 'desc',
name: '提示信息',
type: 'TextArea',
},
{
key: 'link',
name: '跳转链接',
type: 'Text',
},
],
config: {
bgColor: 'rgba(228,162,22,1)',
money: 50,
link: 'http://h5.dooring.cn',
ifText: '满199元使用',
dealTime: '2020.02.12-02.16',
desc: '有家店铺',
},
};
export default ZhuanLan;

View File

@ -0,0 +1,6 @@
const template = {
type: 'Coupons',
h: 72,
displayName: '优惠券组件',
};
export default template;

View File

@ -0,0 +1,47 @@
.list {
margin: 20px auto;
width: 94%;
.searchWrap {
margin-bottom: 16px;
display: flex;
width: 100%;
height: 36px;
border-radius: 30px;
background-color: #f0f0f0;
input {
display: inline-block;
padding-left: 12px;
flex: 1;
border: none;
background-color: transparent;
}
.searchBtn {
margin-left: 10px;
margin-right: 10px;
line-height: 36px;
font-size: 18px;
display: inline-block;
cursor: pointer;
}
}
.sourceList {
.sourceItem {
position: relative;
display: flex;
align-items: center;
margin-bottom: 16px;
.content {
margin-left: 12px;
.tit {
line-height: 2;
}
}
.price {
position: absolute;
right: 12px;
bottom: 0px;
color: red;
}
}
}
}

View File

@ -0,0 +1,81 @@
import React, { memo, useState, useRef } from 'react';
import { SearchOutlined } from '@ant-design/icons';
import styles from './index.less';
import { IListConfig } from './schema';
import logo from '@/assets/07-列表.png';
interface ListType extends IListConfig {
isTpl?: boolean;
}
const List = memo((props: ListType) => {
const { round, sourceData, isSearch, imgSize, fontSize, color, padding } = props;
const [data, setData] = useState(sourceData);
const iptRef: any = useRef(null);
const handleSearch = () => {
let keyword = iptRef?.current?.value;
if (keyword) {
setData(prev => {
return prev.filter(
item => item.title.indexOf(keyword) > -1 || item.desc.indexOf(keyword) > -1,
);
});
return;
}
setData(sourceData);
};
return props.isTpl ? (
<div>
<img style={{ width: '100%' }} src={logo} alt="" />
</div>
) : (
<div className={styles.list}>
{isSearch && (
<div className={styles.searchWrap}>
<input type="text" ref={iptRef} />
<span className={styles.searchBtn} onClick={handleSearch}>
<SearchOutlined />
</span>
</div>
)}
<div className={styles.sourceList}>
{data.map((item, i) => {
return (
<div className={styles.sourceItem} key={i} style={{ marginBottom: padding + 'px' }}>
<div className={styles.imgWrap}>
<img
src={item.imgUrl[0] && item.imgUrl[0].url}
alt={item.desc}
style={{
width: parseFloat(imgSize),
height: imgSize + 'px',
objectFit: 'cover',
borderRadius: round,
}}
/>
</div>
<div className={styles.content}>
<a
className={styles.tit}
style={{ fontSize, color }}
href={item.link ? item.link : '#'}
>
{item.title}
<div
className={styles.desc}
style={{ fontSize: fontSize * 0.8, color: 'rgba(0,0,0, .3)' }}
>
{item.desc}
</div>
</a>
</div>
<span className={styles.price}>{item.price}</span>
</div>
);
})}
</div>
</div>
);
});
export default List;

View File

@ -0,0 +1,142 @@
import {
IColorConfigType,
IDataListConfigType,
INumberConfigType,
ISelectConfigType,
TColorDefaultType,
ISwitchConfigType,
TDataListDefaultType,
TNumberDefaultType,
TSelectDefaultType,
TSwitchDefaultType,
} from '@/core/FormComponents/types';
import { serverUrl } from '@/utils/tool';
export type TListSelectKeyType = '60' | '80' | '100' | '120' | '150';
export type TListEditData = Array<
| IColorConfigType
| IDataListConfigType
| INumberConfigType
| ISelectConfigType<TListSelectKeyType>
| ISwitchConfigType
>;
export interface IListConfig {
sourceData: TDataListDefaultType;
isSearch: TSwitchDefaultType;
padding: number;
round: TNumberDefaultType;
imgSize: TSelectDefaultType<TListSelectKeyType>;
fontSize: TNumberDefaultType;
color: TColorDefaultType;
}
export interface IListSchema {
editData: TListEditData;
config: IListConfig;
}
const List: IListSchema = {
editData: [
{
key: 'sourceData',
name: '数据源',
type: 'DataList',
cropRate: 1,
},
{
key: 'isSearch',
name: '是否搜索',
type: 'Switch',
},
{
key: 'padding',
name: '列表项间距',
type: 'Number',
},
{
key: 'round',
name: '圆角',
type: 'Number',
},
{
key: 'imgSize',
name: '图片大小',
type: 'Select',
range: [
{
key: '60',
text: '60 x 60',
},
{
key: '80',
text: '80 x 80',
},
{
key: '100',
text: '100 x 100',
},
{
key: '120',
text: '120 x 120',
},
{
key: '150',
text: '150 x 150',
},
],
},
{
key: 'fontSize',
name: '文字大小',
type: 'Number',
},
{
key: 'color',
name: '文字颜色',
type: 'Color',
},
],
config: {
sourceData: [
{
id: '1',
title: '趣谈小课',
desc: '致力于打造优质小课程',
price: '免费',
link: 'xxxxx',
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/1_1740c6fbcd9.png`,
},
],
},
{
id: '2',
title: '趣谈小课',
desc: '致力于打造优质小课程',
price: '免费',
link: 'xxxxx',
imgUrl: [
{
uid: '002',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/1_1740c6fbcd9.png`,
},
],
},
],
isSearch: false,
padding: 16,
round: 0,
imgSize: '80',
fontSize: 16,
color: 'rgba(153,153,153,1)',
},
};
export default List;

View File

@ -0,0 +1,6 @@
const template = {
type: 'List',
h: 110,
displayName: '列表组件',
};
export default template;

View File

@ -0,0 +1,34 @@
.tabWrap {
padding-top: 16px;
padding-bottom: 16px;
.content {
display: flex;
flex-wrap: wrap;
.item {
position: relative;
padding: 20px 20px 0;
width: 50%;
text-align: center;
justify-content: center;
.imgWrap {
display: inline-block;
width: 80%;
img {
border-radius: 6px;
width: 120px;
height: 120px;
object-fit: cover;
}
.title {
line-height: 2.4;
}
}
.price {
position: absolute;
right: 26px;
bottom: -12px;
color: red;
}
}
}
}

View File

@ -0,0 +1,67 @@
import React, { useEffect, useRef } from 'react';
import { Tabs } from 'zarm';
import styles from './index.less';
import { ITabConfig } from './schema';
import logo from '@/assets/11-切换页.png';
interface TabType extends ITabConfig {
isTpl?: boolean;
}
const { Panel } = Tabs;
const XTab = (props: TabType) => {
const { tabs = ['分类一', '分类二'], activeColor, color, fontSize, sourceData, isTpl } = props;
const tabWrapRef = useRef<HTMLDivElement>(null);
useEffect(() => {
if (tabWrapRef.current) {
let res = tabWrapRef.current.querySelector('.za-tabs__line') as HTMLElement;
if (res) {
res.style.backgroundColor = activeColor;
}
}
}, [activeColor]);
return isTpl ? (
<div>
<img style={{ width: '100%' }} src={logo} alt=""></img>
</div>
) : (
<div className={styles.tabWrap} ref={tabWrapRef}>
<Tabs
scrollThreshold={3}
onChange={i => {
console.log(i);
}}
>
{tabs.map((item, i) => {
return (
<Panel title={item} key={i}>
<div className={styles.content}>
{sourceData
.filter(item => item.type === i)
.map((item, i) => {
return (
<div className={styles.item} key={i}>
<a className={styles.imgWrap} href={item.link} title={item.desc}>
<img src={item.imgUrl[0] && item.imgUrl[0].url} alt={item.title} />
<div className={styles.title} style={{ fontSize, color }}>
{item.title}
</div>
</a>
<span className={styles.price}> {item.price} </span>
</div>
);
})}
</div>
</Panel>
);
})}
</Tabs>
</div>
);
};
export default XTab;

View File

@ -0,0 +1,123 @@
import {
IColorConfigType,
IDataListConfigType,
IMutiTextConfigType,
INumberConfigType,
TColorDefaultType,
TDataListDefaultType,
TMutiTextDefaultType,
TNumberDefaultType,
} from '@/core/FormComponents/types';
import { serverUrl } from '@/utils/tool';
export type TTabEditData = Array<
IMutiTextConfigType | IColorConfigType | INumberConfigType | IDataListConfigType
>;
export interface ITabConfig {
tabs: TMutiTextDefaultType;
color: TColorDefaultType;
activeColor: TColorDefaultType;
fontSize: TNumberDefaultType;
imgSize: TNumberDefaultType;
sourceData: TDataListDefaultType;
}
export interface ITabSchema {
editData: TTabEditData;
config: ITabConfig;
}
const Tab: ITabSchema = {
editData: [
{
key: 'tabs',
name: '项目类别',
type: 'MutiText',
},
{
key: 'activeColor',
name: '激活颜色',
type: 'Color',
},
{
key: 'color',
name: '文字颜色',
type: 'Color',
},
{
key: 'fontSize',
name: '文字大小',
type: 'Number',
},
{
key: 'imgSize',
name: '图片大小',
type: 'Number',
},
{
key: 'sourceData',
name: '数据源',
type: 'DataList',
},
],
config: {
tabs: ['类别一', '类别二'],
color: 'rgba(153,153,153,1)',
activeColor: 'rgba(0,102,204,1)',
fontSize: 16,
imgSize: 100,
sourceData: [
{
id: '1',
title: '趣谈小课1',
desc: '致力于打造优质小课程',
price: '',
link: 'xxxxx',
type: 0,
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/1_1740c6fbcd9.png`,
},
],
},
{
id: '2',
title: '趣谈小课2',
desc: '致力于打造优质小课程',
price: '',
link: 'xxxxx',
type: 0,
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/2_1740c7033a9.png`,
},
],
},
{
id: '3',
title: '趣谈小课3',
desc: '致力于打造优质小课程',
price: '',
link: 'xxxxx',
type: 1,
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/1_1740c6fbcd9.png`,
},
],
},
],
},
};
export default Tab;

View File

@ -0,0 +1,6 @@
const template = {
type: 'Tab',
h: 130,
displayName: '切换页组件',
};
export default template;

View File

@ -0,0 +1,47 @@
.topArea {
display: flex;
.tx {
flex-shrink: 0;
width: 72px;
height: 72px;
border-radius: 6px;
background-color: #f0f0f0;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.textArea {
margin-left: 10px;
margin-right: 10px;
.title {
font-weight: bold;
line-height: 2.4;
}
.desc {
opacity: 0.6;
}
}
.btnArea {
margin-left: auto;
margin-top: 3px;
flex-shrink: 0;
.btn {
display: inline-block;
padding: 3px 8px;
border-radius: 4px;
font-size: 12px;
color: #fff;
}
}
}
.content {
margin-top: 16px;
p {
margin-bottom: 2px;
word-wrap: break-word;
}
}

View File

@ -0,0 +1,73 @@
import React, { memo } from 'react';
import { IZLConfig } from './schema';
import logo from '@/assets/zhuanlan.png';
import styles from './index.less';
interface IProps extends IZLConfig {
isTpl?: boolean;
}
const ZL = memo((props: IProps) => {
const {
title,
desc,
imgUrl,
link,
linkText,
linkBg,
titColor,
titFontSize,
bgColor,
padding,
radius,
content,
isTpl,
} = props;
const toLink = () => {
if (link && window.location.href.indexOf('editor') < 0) {
window.location.href = link;
}
};
return isTpl ? (
<div>
<img style={{ width: '100%' }} src={logo} alt=""></img>
</div>
) : (
<div
style={{
width: 'calc(100% - 32px)',
backgroundColor: bgColor,
padding: padding + 'px',
borderRadius: radius + 'px',
margin: '16px auto',
boxShadow: '0 0 6px rgba(0,0,0, .1)',
}}
>
<div className={styles.topArea}>
<div className={styles.tx}>
<img src={imgUrl && imgUrl[0].url} alt="dooring" />
</div>
<div className={styles.textArea}>
<div className={styles.title} style={{ fontSize: titFontSize + 'px', color: titColor }}>
{title}
</div>
<div
className={styles.desc}
style={{ fontSize: Math.ceil(titFontSize * 0.7) + 'px', color: titColor }}
>
{desc}
</div>
</div>
<div className={styles.btnArea}>
<span className={styles.btn} style={{ backgroundColor: linkBg }} onClick={toLink}>
{' '}
{linkText}{' '}
</span>
</div>
</div>
<div className={styles.content} dangerouslySetInnerHTML={{ __html: content }}></div>
</div>
);
});
export default ZL;

View File

@ -0,0 +1,134 @@
import {
IColorConfigType,
INumberConfigType,
ITextConfigType,
ITextAreaConfigType,
IUploadConfigType,
IRichTextConfigType,
TColorDefaultType,
TNumberDefaultType,
TTextDefaultType,
TUploadDefaultType,
TTextAreaDefaultType,
TRichTextDefaultType,
} from '@/core/FormComponents/types';
import { serverUrl } from '@/utils/tool';
export type TZLEditData = Array<
| IUploadConfigType
| ITextConfigType
| IColorConfigType
| INumberConfigType
| ITextAreaConfigType
| IRichTextConfigType
>;
export interface IZLConfig {
bgColor: TColorDefaultType;
padding: TNumberDefaultType;
radius: TNumberDefaultType;
link: TTextDefaultType;
linkText: TTextDefaultType;
linkBg: TColorDefaultType;
imgUrl: TUploadDefaultType;
title: TTextDefaultType;
desc: TTextAreaDefaultType;
titColor: TColorDefaultType;
titFontSize: TNumberDefaultType;
content: TRichTextDefaultType;
}
export interface ICardSchema {
editData: TZLEditData;
config: IZLConfig;
}
const ZhuanLan: ICardSchema = {
editData: [
{
key: 'title',
name: '标题',
type: 'Text',
},
{
key: 'titColor',
name: '标题颜色',
type: 'Color',
},
{
key: 'titFontSize',
name: '标题大小',
type: 'Number',
},
{
key: 'desc',
name: '描述',
type: 'TextArea',
},
{
key: 'imgUrl',
name: '专栏图片',
type: 'Upload',
isCrop: true,
cropRate: 1,
},
{
key: 'bgColor',
name: '背景色',
type: 'Color',
},
{
key: 'padding',
name: '内容边距',
type: 'Number',
},
{
key: 'radius',
name: '圆角',
type: 'Number',
},
{
key: 'linkText',
name: '按钮文本',
type: 'Text',
},
{
key: 'linkBg',
name: '按钮背景色',
type: 'Color',
},
{
key: 'link',
name: '按钮跳转链接',
type: 'Text',
},
{
key: 'content',
name: '详细介绍',
type: 'RichText',
},
],
config: {
imgUrl: [
{
uid: '001',
name: 'image.png',
status: 'done',
url: `${serverUrl}/uploads/code_173e1705e0c.png`,
},
],
title: '趣谈前端',
desc: '一个有点意思的技术社区~',
titColor: 'rgba(0,0,0,1)',
titFontSize: 18,
bgColor: 'rgba(255,255,255,1)',
padding: 16,
radius: 6,
link: '',
linkText: '订阅',
linkBg: 'rgba(22,40,212,1)',
content: '趣谈前端 - 可视化专栏',
},
};
export default ZhuanLan;

View File

@ -0,0 +1,6 @@
const template = {
type: 'ZhuanLan',
h: 120,
displayName: '专栏组件',
};
export default template;

View File

@ -0,0 +1,14 @@
import ZhuanLan from './ZhuanLan/schema';
import Tab from './Tab/schema';
import List from './List/schema';
import Coupons from './Coupons/schema';
import CardLabel from './CardLabel/schema';
const shopSchema = {
ZhuanLan,
Tab,
List,
Coupons,
CardLabel,
};
export default shopSchema;

View File

@ -0,0 +1,12 @@
import ZhuanLan from './ZhuanLan/template';
import Tab from './Tab/template';
import List from './List/template';
import Coupons from './Coupons/template';
import CardLabel from './CardLabel/template';
const basicTemplate = [ZhuanLan, List, Tab, Coupons, CardLabel];
const ShopTemplate = basicTemplate.map(v => {
return { ...v, category: 'shop' };
});
export default ShopTemplate;

View File

@ -1,11 +1,13 @@
import BasicSchema from './BasicComponents/schema';
import MediaSchema from './MediaComponents/schema';
import VisualSchema from './VisualComponents/schema';
import shopSchema from './ShopComponents/schema';
const schema = {
...BasicSchema,
...MediaSchema,
...VisualSchema,
...shopSchema,
};
export default schema;