Commit a6a0885f authored by marsandheart's avatar marsandheart

添加app的Loading组件,通过redux控制

parent f8f90ae4
......@@ -2,15 +2,17 @@ import React from 'react';
import { Provider } from 'react-redux';
import './assets/css/basic.css';
import store from './store/index';
import Router from './Router';
import Loading from './components/Loading';
function App() {
return (
<Provider store={store}>
<div>
<Router />
<Loading />
</div>
</Provider>
);
}
......
import React from 'react';
import { connect } from 'react-redux';
import styles from './Loading.module.scss';
import { Spin } from 'antd';
const Loading = (props) => {
return props.visible ? (
<div className={styles.loading}>
<Spin tip="Loading..."></Spin>
</div>
) : (
<div></div>
);
};
const mapState = (state) => ({
visible: state.app.loadingQueue > 0
});
export default connect(mapState, null)(Loading);
.loading{
position: absolute;
background-color: rgba($color: #000000, $alpha: 0.3);
padding: 20px;
border-radius: 10px;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
\ No newline at end of file
import * as React from 'react';
// interface IProps {
// className?: string;
// onClick?: (ev: React.MouseEvent<HTMLDivElement>) => any;
// }
// type IState = Readonly<{
// style: React.CSSProperties;
// }>;
class TouchOpacity extends React.Component {
constructor(props) {
super(props);
this.state = {
style: {
opacity: 1
}
};
this.timer = null;
}
onClick = (ev) => {
const { onClick } = this.props;
ev.stopPropagation();
this.setState(
{
style: {
opacity: 0.5
}
},
() => {
this.timer = setTimeout(() => {
this.setState({
style: {
opacity: 1
}
});
}, 50);
}
);
if (onClick) {
onClick(ev);
}
};
componentWillUnmount() {
clearTimeout(this.timer);
}
render() {
const { children, onClick, ...otherProps } = this.props;
return (
<span {...otherProps} style={this.state.style} onClick={this.onClick}>
{children}
</span>
);
}
}
export default TouchOpacity;
......@@ -183,7 +183,8 @@ const defaultSteps = [
至少3秒,保证标题清晰后给投保人阅读
</span>
),
voice: '请销售人员点击链接向镜头展示《免除保险人责任条款》至少3秒,保证标题清晰后给投保人阅读'
voice:
'请销售人员点击链接向镜头展示《免除保险人责任条款》至少3秒,保证标题清晰后给投保人阅读'
}
]
},
......@@ -449,7 +450,7 @@ export default function(props) {
const toStep = (sId) => {
setStepId(sId);
setQuestionId('1');
}
};
return (
<div className={styles.page}>
......
import React, { useState } from 'react';
import { connect } from 'react-redux';
import { Table, Divider } from 'antd';
import 'antd/dist/antd.css';
......@@ -14,6 +15,7 @@ import IconReturn from 'assets/img/return.png';
import IconHome from 'assets/img/home.png';
import TouchOpacity from '../components/TouchOpacity';
import TouchSpan from '../components/TouchSpan';
import TabTitle from './InsuredsInfo.components/TabTitle';
import ProductListModal from './InsuredsInfo.components/ProductListModal';
......@@ -36,7 +38,15 @@ const initTableData = [
}
];
const columns = [
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const InsuredInfo = (props) => {
const { history, showLoading, hideLoading } = props;
const [selectedDataKey, setSelectedDataKey] = useState('');
const [tableData, setTableData] = useState(initTableData);
const [modalVisible, setModalVisible] = useState(false);
const columns = [
{
title: '保险计划',
dataIndex: 'plan',
......@@ -68,25 +78,37 @@ const columns = [
key: 'action',
render: (text, record) => (
<div>
<span className={styles.actText}>修改保额</span>
<TouchSpan className={styles.actText}>修改保额</TouchSpan>
<Divider type="vertical" />
<span className={styles.actText}>删除</span>
<TouchSpan
className={record.key === '1' ? styles.actTextDefault : styles.actText}
onClick={() => {
removeTableData(record.key);
}}
>
删除
</TouchSpan>
</div>
)
}
];
export default function(props) {
const { history } = props;
const [selectedDataKey, setSelectedDataKey] = useState('');
const [tableData, setTableData] = useState(initTableData);
const [modalVisible, setModalVisible] = useState(false);
];
const addPolicy = () => {
setModalVisible(!modalVisible);
};
const addTableData = (product) => {
const removeTableData = async (key) => {
showLoading();
await sleep(500);
hideLoading();
const newTableData = tableData.filter((ele) => ele.key !== key);
setTableData(newTableData);
};
const addTableData = async (product) => {
showLoading();
await sleep(500);
hideLoading();
const key = String(tableData.length + 1);
setSelectedDataKey(key);
setTableData([
......@@ -126,7 +148,7 @@ export default function(props) {
<img alt="pay" src={IconMoney} className={styles.titleIcon} />
<span>借/领/退款</span>
</TabTitle>
<div className={styles.user} >
<div className={styles.user}>
<div>
<img src={IconReturn} alt="return"></img>
<img src={IconHome} alt="home"></img>
......@@ -167,9 +189,9 @@ export default function(props) {
<span>付款账号:622********3042</span>
</div>
<div className={styles.premLine}>
<span>原保费:559</span>
<span>原保费:680</span>
<span>
下一期保费:<span className={styles.actText}>762</span>
下一期保费:<span className={styles.actText}>{tableData.length * 180 + 500}</span>
</span>
<TouchOpacity className={styles.actText}>
<img src={IconDetail} alt="detail"></img>
......@@ -197,10 +219,18 @@ export default function(props) {
<ProductListModal
visible={modalVisible}
addTableData={addTableData}
showLoading={showLoading}
hideLoading={hideLoading}
close={() => {
setModalVisible(false);
}}
/>
</div>
);
}
};
const mapDispatch = ({ app: { showLoading, hideLoading } }) => ({
showLoading,
hideLoading
});
export default connect(null, mapDispatch)(InsuredInfo);
......@@ -124,6 +124,11 @@
}
}
.actTextDefault{
@extend .actText;
color: #D7D4D7;
}
.accountLine{
display: flex;
flex-direction: row-reverse;
......
import React, { useState } from 'react';
import { Spin } from 'antd';
import styles from './ProductListModal.module.scss';
import TouchOpacity from '../../components/TouchOpacity';
......@@ -77,9 +76,8 @@ const productList = [
];
export default function(props) {
const { visible, addTableData, close } = props;
const { visible, addTableData, close, showLoading, hideLoading } = props;
const [productId, setProductId] = useState('');
const [loadingVisible, toggleLoadingVisible] = useState(false);
const clickMain = (event) => {
// 点击主体的时候禁止冒泡,不关闭modal
......@@ -90,17 +88,17 @@ export default function(props) {
if (productId === id) {
setProductId('');
} else {
toggleLoadingVisible(true);
showLoading();
setTimeout(() => {
setProductId(id);
toggleLoadingVisible(false);
hideLoading();
}, Math.random() * 1000);
}
};
const reset = () => {
setProductId('');
}
};
const submit = () => {
const selectedProduct = productList.find((p) => p.id === productId);
......@@ -121,7 +119,9 @@ export default function(props) {
<div className={styles.info}>
<span>被保险人出生日期:1974年08月07日</span>
<span>请谨慎选择以下产品的成人或儿童计划</span>
<TouchOpacity className={styles.btn} onClick={reset}>重置</TouchOpacity>
<TouchOpacity className={styles.btn} onClick={reset}>
重置
</TouchOpacity>
</div>
<div className={styles.list}>
{productList.map((ele) => (
......@@ -138,18 +138,15 @@ export default function(props) {
))}
</div>
<div className={styles.footer}>
<TouchOpacity className={styles.btnCancel} onClick={close}>取消</TouchOpacity>
<TouchOpacity className={styles.btnCancel} onClick={close}>
取消
</TouchOpacity>
<TouchOpacity className={styles.btn} onClick={submit}>
确定
</TouchOpacity>
</div>
</div>
</div>
{loadingVisible && (
<div className={styles.loading}>
<Spin tip="Loading..."></Spin>
</div>
)}
</div>
);
}
......@@ -128,13 +128,3 @@ $itemWidth: 22vw;
margin-left: 30%;
}
}
.loading{
position: absolute;
background-color: rgba($color: #000000, $alpha: 0.3);
padding: 20px;
border-radius: 10px;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
\ No newline at end of file
const app = {
state: {
loadingQueue: 0
},
reducers: {
showLoading(state) {
return {
...state,
loadingQueue: state.loadingQueue + 1
};
},
hideLoading(state) {
return {
...state,
loadingQueue: state.loadingQueue - 1
};
}
}
};
export default app;
import { init } from '@rematch/core';
import count from './count';
import app from './app';
const store = init({
models: {
count
count,
app
}
});
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment