Commit bb531ad1 authored by 2breakegg's avatar 2breakegg

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/index.js
#	src/routes/Activate.js
#	src/routes/Login.js
#	src/routes/Profiles.js
parents a86acf53 b007630f
import React from 'react'; import React from 'react';
import styles from './EmailForm.css'; import styles from './EmailForm.css';
import {connect} from 'react-redux' import { connect } from 'react-redux'
import { Form, Input, Icon, Button } from 'antd' import { Form, Input, Icon, Button, Modal } from 'antd'
const FormItem = Form.Item; const FormItem = Form.Item;
import SubmitButton from './SubmitButton' import SubmitButton from './SubmitButton'
...@@ -14,25 +14,25 @@ const formItemLayout = { ...@@ -14,25 +14,25 @@ const formItemLayout = {
class EmailForm extends React.Component { class EmailForm extends React.Component {
onSubmit = (e) => { onSubmit = (e) => {
const { form, dispatch, data: {id} } = this.props const { form, dispatch, data: { id } } = this.props
e && e.preventDefault(); e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
const { email, password } = values const { email, password } = values
dispatch({type: "user/updateEmail", payload: { email, password, user_id: id }}) dispatch({ type: "user/updateEmail", payload: { email, password, user_id: id } })
} }
}); });
} }
render(){ render() {
const {form, dispatch, data, checkEmail, isEmailExists} = this.props const { form, dispatch, data, checkEmail, isEmailExists, isSendEmailActive } = this.props
const {getFieldDecorator} = form const { getFieldDecorator } = form;
const {id, email} = data const { id, email } = data;
const emailProps = { const emailProps = {
fromItem: { fromItem: {
...@@ -43,7 +43,7 @@ class EmailForm extends React.Component { ...@@ -43,7 +43,7 @@ class EmailForm extends React.Component {
...formItemLayout ...formItemLayout
}, },
decorator: { decorator: {
initialValue: email initialValue: email
}, },
input: { input: {
placeholder: "email" placeholder: "email"
...@@ -52,7 +52,7 @@ class EmailForm extends React.Component { ...@@ -52,7 +52,7 @@ class EmailForm extends React.Component {
const passwordProps = { const passwordProps = {
fromItem: { fromItem: {
label: "passwrod", label: "passwrod",
...formItemLayout ...formItemLayout
}, },
decorator: { decorator: {
...@@ -65,20 +65,14 @@ class EmailForm extends React.Component { ...@@ -65,20 +65,14 @@ class EmailForm extends React.Component {
type: 'password' type: 'password'
} }
} }
return ( return (
<Form onSubmit={this.onSubmit}> <Form onSubmit={this.onSubmit}>
<FormItem {...emailProps.fromItem}> <FormItem {...emailProps.fromItem}>
{getFieldDecorator(`email`, {...emailProps.decorator})( {getFieldDecorator('email', { ...emailProps.decorator })(
<Input <Input
{...emailProps.input} {...emailProps.input}
onBlur = {() => dispatch({type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id} })}/> onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })} />
)}
</FormItem>
<FormItem {...passwordProps.fromItem}>
{getFieldDecorator(`password`, {...passwordProps.decorator})(
<Input {...passwordProps.input} />
)} )}
</FormItem> </FormItem>
...@@ -94,13 +88,14 @@ class EmailForm extends React.Component { ...@@ -94,13 +88,14 @@ class EmailForm extends React.Component {
function mapStateToProps(state, props) { function mapStateToProps(state, props) {
const { const {
user: {data}, user: { data },
auth: {isEmailExists, checkEmail} auth: { isEmailExists, checkEmail, isSendEmailActive }
} = state } = state
return { return {
data, data,
checkEmail, checkEmail,
isEmailExists isEmailExists,
isSendEmailActive
}; };
} }
......
...@@ -2,10 +2,10 @@ import { Button } from 'antd'; ...@@ -2,10 +2,10 @@ import { Button } from 'antd';
import React from 'react'; import React from 'react';
import styles from './SubmitButton.css'; import styles from './SubmitButton.css';
function SubmitButton() { function SubmitButton(props) {
return ( return (
<div className={styles.wrapSubmit}> <div className={styles.wrapSubmit}>
<Button type="primary" htmlType="submit" size="large">提交</Button> <Button type="primary" htmlType="submit" size="large" {...props} >提交</Button>
</div> </div>
); );
} }
......
export default { export default {
// apiRoot: 'http://localhost:3000', apiRoot: 'http://localhost:3000',
apiRoot: 'http://192.168.1.126:3000',
}; };
html, body, :global(#root) {
height: 100%;
}
...@@ -2,13 +2,14 @@ import { message } from 'antd'; ...@@ -2,13 +2,14 @@ import { message } from 'antd';
import dva from 'dva'; import dva from 'dva';
import { browserHistory } from 'dva/router'; import { browserHistory } from 'dva/router';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import createLoading from 'dva-loading'
import { addLocaleData, IntlProvider } from 'react-intl'; import { addLocaleData, IntlProvider } from 'react-intl';
// 5. Start
import en from 'react-intl/locale-data/en'; import en from 'react-intl/locale-data/en';
import zh from 'react-intl/locale-data/zh'; import zh from 'react-intl/locale-data/zh';
import localeData from '../i18n.json'; import localeData from '../i18n.json';
import './index.css'; import './index.less';
import { IntlProvider, addLocaleData } from 'react-intl';
// 1. Initialize // 1. Initialize
const app = dva({ const app = dva({
...@@ -19,6 +20,8 @@ const app = dva({ ...@@ -19,6 +20,8 @@ const app = dva({
history: browserHistory, history: browserHistory,
}); });
app.use(createLoading())
app.model(require('./models/user')); app.model(require('./models/user'));
...@@ -40,15 +43,22 @@ app.model(require('./models/common')); ...@@ -40,15 +43,22 @@ app.model(require('./models/common'));
// 4. Router // 4. Router
app.router(require('./router')); app.router(require('./router'));
// 5. Start
addLocaleData([...en, ...zh]); addLocaleData([...en, ...zh]);
/*eslint-disable */ /*eslint-disable */
const language = navigator.language || (navigator.languages && navigator.languages[0]) || navigator.userLanguage; let language = navigator.language || (navigator.languages && navigator.languages[0]) || navigator.userLanguage;
/*eslint-enable */ /*eslint-enable */
const languageWithoutRegionCode = 'zh' || language.toLowerCase().split(/[_-]+/)[0]; const languageWithoutRegionCode = language.toLowerCase().split(/[_-]+/)[0];
const messages = localeData[languageWithoutRegionCode] || localeData[language] || localeData.zh; const messages = localeData[languageWithoutRegionCode] || localeData[language] || localeData.zh;
if(localStorage.getItem('locale')){
language = JSON.parse(localStorage.getItem('locale'))
}
const App = app.start(); const App = app.start();
ReactDOM.render( ReactDOM.render(
<IntlProvider locale={language} messages={messages}> <IntlProvider locale={language} messages={messages}>
......
html, body, :global(#root) {
height: 100%;
}
:global {
.example-enter {
opacity: 0.01;
}
.example-enter.example-enter-active {
opacity: 1;
transition: opacity 500ms ease-in;
}
.example-leave {
opacity: 1;
}
.example-leave.example-leave-active {
opacity: 0.01;
transition: opacity 300ms ease-in;
}
}
\ No newline at end of file
import { login, forgot, register, reset, activate, checkUserExists } from '../services/auth' import { login, forgot, register, reset, activate, checkUserExists } from '../services/auth'
import { message } from 'antd' import { message } from 'antd'
import { routerRedux } from 'dva/router'
export default { export default {
namespace: 'auth', namespace: 'auth',
state: { state: {
input:{},
activateState: false, activateState: false,
checkEmail: '', checkEmail: '',
checkUsername: '', checkUsername: '',
...@@ -80,7 +83,7 @@ export default { ...@@ -80,7 +83,7 @@ export default {
}, },
loginSuccess(state, action) { loginSuccess(state, action) {
return { return {
...state, ...{ ...state, ...action.payload, ...{
isLoginSubmit: false, isLoginSubmit: false,
} }
}; };
...@@ -137,37 +140,48 @@ export default { ...@@ -137,37 +140,48 @@ export default {
}, },
effects: { effects: {
*activate({ payload }, { call, put }) { *activate({ payload }, { call, put }) {
const { data } = yield call(activate, payload) try {
const { data } = yield call(activate, payload)
if(data) {
message.success("激活成功")
}
} catch (error) {
message.error(error.message)
}
}, },
*checkEmail({ payload }, { call, put }) { *checkEmail({ payload }, { call, put }) {
const { data } = yield call(checkUserExists, payload)
console.log(data); try {
if(data) { const { data } = yield call(checkUserExists, payload)
yield put({ type: 'check', payload: { isEmailExists: true , checkEmail: 'warning'}}) if (data) {
} else { yield put({ type: 'check', payload: { isEmailExists: true, checkEmail: 'warning' } })
yield put({ type: 'check', payload: { isEmailExists: false , checkEmail: 'success'}}) }
} catch (error) {
yield put({ type: 'check', payload: { isEmailExists: false, checkEmail: 'success' } })
} }
}, },
*checkUsername({ payload }, { call, put }) { *checkUsername({ payload }, { call, put }) {
const { data } = yield call(checkUserExists, payload) try {
const { data } = yield call(checkUserExists, payload)
if (data) {
yield put({ type: 'check', payload: { isUserNameExists: true, checkUsername: 'warning' } })
}
} catch (error) {
yield put({ type: 'check', payload: { isUserNameExists: false, checkUsername: 'success' } })
if(data) {
yield put({ type: 'check', payload: { isUserNameExists: true , checkUsername: 'warning'}})
} else {
yield put({ type: 'check', payload: { isUserNameExists: false , checkUsername: 'success'}})
} }
}, },
*login({ payload }, { call, put }) { *login({ payload }, { call, put }) {
const {data} = yield call(login, payload) try {
const { data } = yield call(login, payload)
if(data){ if (data) {
yield put({ type: 'loginSuccess' }) yield put({ type: 'loginSuccess', payload: { input: payload } })
yield put({ type: 'user/loginSuccess', payload: { data } }) yield put({ type: 'user/loginSuccess', payload: { data } })
message.info("登录成功")
} else {
yield put({ type: 'loginFail' })
message.error("登陆失败")
} }
} catch (error) {
yield put({ type: 'loginFail' })
message.error(error.message)
}
}, },
*forgot({ payload }, { call, put }) { *forgot({ payload }, { call, put }) {
try { try {
...@@ -182,26 +196,30 @@ export default { ...@@ -182,26 +196,30 @@ export default {
} }
}, },
*register({ payload }, { call, put }) { *register({ payload }, { call, put }) {
const {data} = yield call(register, payload)
if(data) { try {
yield put({ type: 'registerSuccess'}) const { data } = yield call(register, payload)
message.info("注册成功") if (data) {
} else { yield put({ type: 'registerSuccess' })
yield put({ type: 'registerFail' }) message.info("注册成功, 请验证激活邮件~", 3)
message.error("注册失败") yield put(routerRedux.replace("/verify"))
} }
} catch (error) {
yield put({ type: 'registerFail' })
message.error("注册失败")
}
}, },
*reset({ payload }, { call, put }) { *reset({ payload }, { call, put }) {
const { data } = yield call(reset, payload) try {
const { data } = yield call(reset, payload)
if(data){ if (data) {
yield put({ type: 'resetSuccess' }) yield put({ type: 'resetSuccess' })
message.info("重置成功") message.info("重置成功")
}else{
yield put({ type: 'resetFail' })
message.error("重置失败")
} }
} catch (error) {
yield put({ type: 'resetFail' })
message.error("重置失败")
}
}, },
}, },
subscriptions: {}, subscriptions: {},
......
...@@ -66,15 +66,26 @@ export default { ...@@ -66,15 +66,26 @@ export default {
effects: { effects: {
*loginSuccess({ payload }, { call, put }) { *loginSuccess({ payload }, { call, put }) {
localStorage.setItem("user", JSON.stringify(payload.data)) const {data} = payload
yield put(routerRedux.replace("/profiles")) if(!data) {
message.error("error ")
}
if(data.active) {
yield put(routerRedux.replace("/profiles"))
message.info("登录成功")
localStorage.setItem("user", JSON.stringify(payload.data))
} else {
yield put(routerRedux.replace(`/verify`))
}
}, },
*preLogin({ payload }, { call, put }) { *preLogin({ payload }, { call, put }) {
let user = localStorage.getItem("user") let user = localStorage.getItem("user")
if (!user) { if (!user) {
yield put(routerRedux.replace("/login")) yield put(routerRedux.replace("/signin"))
} }
yield put({ type: 'loginFromStorage', payload: { data: JSON.parse(user) } }) yield put({ type: 'loginFromStorage', payload: { data: JSON.parse(user) } })
......
import { Redirect, Route, Router } from 'dva/router'; import { Redirect, Route, Router } from 'dva/router';
import QueueAnim from 'rc-queue-anim'
import React from 'react'; import React from 'react';
import Active from './routes/Activate.js'; import Active from './routes/Activate.js';
...@@ -13,18 +14,21 @@ import Register from './routes/Register.js'; ...@@ -13,18 +14,21 @@ import Register from './routes/Register.js';
import Reset from './routes/Reset.js'; import Reset from './routes/Reset.js';
import Verify from "./routes/Verify.js";
function RouterConfig({ history }) { function RouterConfig({ history }) {
return ( return (
<Router history={history}> <Router history={history}>
<Redirect from="/" to="/login"/> <Redirect from="/" to="/signin"/>
<Route path="/"> <Route path="/">
<Route path="/login" component={Login}/> <Route path="/signin" component={Login}/>
<Route path="/forgot" component={Forgot}/> <Route path="/forgot" component={Forgot}/>
<Route path="/register" component={Register}/> <Route path="/register" component={Register}/>
<Route path="/reset" component={Reset}/> <Route path="/reset" component={Reset}/>
<Route path="/profiles" component={Profiles}/> <Route path="/profiles" component={Profiles}/>
</Route> </Route>
<Route path="/activate" component={Active}/> <Route path="/activate" component={Active}/>
<Route path="/verify" component={Verify} />
</Router> </Router>
); );
} }
......
...@@ -12,10 +12,10 @@ class Active extends React.Component { ...@@ -12,10 +12,10 @@ class Active extends React.Component {
}; };
render() { render() {
const { activateState } = this.props; const { loading } = this.props;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100%' }}> <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100%' }}>
<Button type="primary" icon="poweroff" loading={activateState} onClick={this.handleClick}> <Button type="primary" icon="poweroff" loading={loading} onClick={this.handleClick}>
<Format id={'verify email'} /> <Format id={'verify email'} />
</Button> </Button>
</div> </div>
...@@ -25,10 +25,12 @@ class Active extends React.Component { ...@@ -25,10 +25,12 @@ class Active extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
const { const {
auth: { activateState },
} = state; } = state;
const loading = state.loading.global || false
return { return {
activateState, loading,
}; };
} }
......
import { Button, Form, Icon, Input, Select, Spin } from 'antd'; import { Button, Form, Icon, Input, Select, Spin, Steps } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import { Link } from 'dva/router'; import { Link } from 'dva/router';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
...@@ -6,6 +6,7 @@ import { FormattedMessage as Format } from 'react-intl'; ...@@ -6,6 +6,7 @@ import { FormattedMessage as Format } from 'react-intl';
const FormItem = Form.Item; const FormItem = Form.Item;
const Option = Select.Option; const Option = Select.Option;
const Step = Steps.Step
const formItemLayout = { const formItemLayout = {
...@@ -44,12 +45,17 @@ class Login extends React.Component { ...@@ -44,12 +45,17 @@ class Login extends React.Component {
const { getFieldDecorator, dispatch } = this.props.form; const { getFieldDecorator, dispatch } = this.props.form;
const { isForgotSubmit = false } = this.props; const { isForgotSubmit = false } = this.props;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={isForgotSubmit} delay={500}> <Spin spinning={loading} delay={100}>
<Form onSubmit={this.onSubmitLogin} className="login-form"> <Form onSubmit={this.onSubmitLogin} className="login-form">
<FormItem>
<Steps size="large" current={0}>
<Step title="Sent Email" icon={<Icon type="solution" />} />
<Step title="Verify Email" icon={<Icon type="mail" />} />
</Steps>
<FormItem style={{ marginTop: '28px'}}>
{getFieldDecorator('email', { {getFieldDecorator('email', {
rules: [{ required: true, message: 'Please input your username or email!' }], rules: [{ required: true, message: 'Please input your username or email!' }],
})( })(
...@@ -68,11 +74,15 @@ class Login extends React.Component { ...@@ -68,11 +74,15 @@ class Login extends React.Component {
} }
} }
function mapStateToProps(state) { function mapStateToProps(state, props) {
const { const {
auth: { isForgotSubmit }, auth: { isForgotSubmit },
} = state; } = state;
const loading = state.loading.global || false
return { return {
loading,
isForgotSubmit, isForgotSubmit,
}; };
} }
......
...@@ -31,12 +31,12 @@ class Login extends React.Component { ...@@ -31,12 +31,12 @@ class Login extends React.Component {
render() { render() {
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form;
const { isLoginSubmit = false } = this.props; const { loading } = this.props;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={isLoginSubmit} delay={500}> <Spin spinning={loading} delay={100}>
<Form onSubmit={this.onSubmitLogin} className="login-form"> <Form onSubmit={this.onSubmitLogin} className="login-form">
<FormItem> <FormItem>
{getFieldDecorator('account', { {getFieldDecorator('account', {
...@@ -74,10 +74,14 @@ class Login extends React.Component { ...@@ -74,10 +74,14 @@ class Login extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
const { const {
auth: { isLoginSubmit }, common: { language },
} = state; } = state;
const loading = state.loading.global || false
return { return {
isLoginSubmit, loading,
language,
}; };
} }
......
:global { :global {
.login-form { .login-form {
max-width: 300px; max-width: 80vw;
min-width: 50vw;
} }
.login-form-forgot { .login-form-forgot {
float: right; float: right;
......
...@@ -30,7 +30,7 @@ class Profiles extends React.Component { ...@@ -30,7 +30,7 @@ class Profiles extends React.Component {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
const { username, nickname, password } = values; const { username, name, password } = values;
dispatch({type: "user/updateProfile", payload: { username, name, password, user_id: id }}) dispatch({type: "user/updateProfile", payload: { username, name, password, user_id: id }})
} }
...@@ -38,7 +38,7 @@ class Profiles extends React.Component { ...@@ -38,7 +38,7 @@ class Profiles extends React.Component {
}; };
render() { render() {
const { dispatch, form, data, isUpdateSubmit=false, checkUsername, isUserNameExists } = this.props; const { dispatch, form, data, isUpdateSubmit=false, checkUsername, isUserNameExists, loading } = this.props
const { getFieldDecorator } = form; const { getFieldDecorator } = form;
const { username, name, id } = data; const { username, name, id } = data;
const { intl: {messages} } = this.context; const { intl: {messages} } = this.context;
...@@ -57,7 +57,7 @@ class Profiles extends React.Component { ...@@ -57,7 +57,7 @@ class Profiles extends React.Component {
} }
return ( return (
<Spin spinning={isUpdateSubmit} delay={500}> <Spin spinning={loading} delay={100}>
<Tabs defaultActiveKey="1" className="app-detail-nav"> <Tabs defaultActiveKey="1" className="app-detail-nav">
<TabPane tab={<span><Icon type="setting" /><Format id={'user-info'} /> </span>} key="1"> <TabPane tab={<span><Icon type="setting" /><Format id={'user-info'} /> </span>} key="1">
<Form onSubmit={this.onUpdateSubmit}> <Form onSubmit={this.onUpdateSubmit}>
...@@ -102,10 +102,14 @@ class Profiles extends React.Component { ...@@ -102,10 +102,14 @@ class Profiles extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
const { const {
user: { data, isUpdateSubmit }, user: { data, isUpdateSubmit },
auth: { checkUsername, isEmailExists, isUserNameExists, }, auth: { checkUsername, isEmailExists, isUserNameExists },
} = state; } = state;
const loading = state.loading.global || false
return { return {
data, data,
loading,
checkUsername, checkUsername,
isEmailExists, isEmailExists,
isUserNameExists, isUserNameExists,
......
import { Button, Form, Icon, Input, Select, Spin } from 'antd'; import { Button, Form, Icon, Input, Select, Spin, Steps } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import { Link } from 'dva/router'; import { Link } from 'dva/router';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FormattedMessage as Format } from 'react-intl'; import { FormattedMessage as Format } from 'react-intl';
import styles from './Register.less'
const FormItem = Form.Item; const FormItem = Form.Item;
const Option = Select.Option; const Option = Select.Option;
const Step = Steps.Step
class Register extends React.Component { class Register extends React.Component {
...@@ -47,7 +49,7 @@ class Register extends React.Component { ...@@ -47,7 +49,7 @@ class Register extends React.Component {
}; };
render() { render() {
const { dispatch, register, form, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit, } = this.props; const { dispatch, register, form, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit, loading } = this.props;
const { getFieldDecorator, } = form; const { getFieldDecorator, } = form;
const { email = {}, username = {}, password = {} } = register; const { email = {}, username = {}, password = {} } = register;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
...@@ -75,9 +77,15 @@ class Register extends React.Component { ...@@ -75,9 +77,15 @@ class Register extends React.Component {
}; };
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
<Spin spinning={isRegisterSubmit} delay={500}>
<Form onSubmit={this.onSubmitLogin} className="login-form"> <Spin spinning={loading} delay={100}>
<Steps size="large" current={0}>
<Step title="register" icon={<Icon type="solution" />} />
<Step title="verify Email" icon={<Icon type="mail" />} />
</Steps>
<Form onSubmit={this.onSubmitLogin} className="login-form" style={{ marginTop: '24px'}}>
<FormItem {...emailProps} > <FormItem {...emailProps} >
{getFieldDecorator('email', { {getFieldDecorator('email', {
rules: [{ rules: [{
...@@ -152,7 +160,11 @@ function mapStateToProps(state) { ...@@ -152,7 +160,11 @@ function mapStateToProps(state) {
const { const {
auth: { register, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit }, auth: { register, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit },
} = state; } = state;
const loading = state.loading.global || false
return { return {
loading,
register, register,
checkEmail, checkEmail,
checkUsername, checkUsername,
......
...@@ -19,3 +19,8 @@ ...@@ -19,3 +19,8 @@
color: #666; color: #666;
} }
} }
.action {
margin-top: 24px;
}
\ No newline at end of file
...@@ -45,7 +45,7 @@ class Reset extends React.Component { ...@@ -45,7 +45,7 @@ class Reset extends React.Component {
const { isResetSubmit = false } = this.props; const { isResetSubmit = false } = this.props;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={isResetSubmit} delay={500}> <Spin spinning={isResetSubmit} delay={100}>
<Form onSubmit={this.onSubmitReset} className="login-form"> <Form onSubmit={this.onSubmitReset} className="login-form">
<FormItem> <FormItem>
......
import React from 'react';
import { connect } from 'dva';
import styles from './Verify.css';
import { Form, Input, Steps, Icon, Spin, Alert, Tag } from 'antd';
import { routerRedux } from 'dva/router'
const FormItem = Form.Item;
import SubmitButton from '../components/SubmitButton'
const Step = Steps.Step
class Verify extends React.Component {
state = {
isChangeEmail: false
}
onSubmit = (e) => {
const { form, dispatch, input: { password }, data: { id }} = this.props;
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const { email } = values
dispatch({ type: 'user/updateEmail', payload: { email, password, user_id: id } });
}
});
};
onReSend = (e) => {
const { dispatch, input: { password }, data: { id, email }} = this.props;
e && e.preventDefault();
dispatch({ type: 'user/updateEmail', payload: { email, password, user_id: id } });
};
render() {
const { form, dispatch, data, checkEmail, isEmailExists, loading, input } = this.props
const { getFieldDecorator } = form;
const { id, email } = data;
const emailProps = {
fromItem: {
label: "修改邮箱",
hasFeedback: true,
validateStatus: checkEmail,
help: isEmailExists ? 'email exists' : '',
},
decorator: {
initialValue: email
},
input: {
placeholder: "email"
}
}
return (
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%' }}>
<Spin spinning={loading} delay={100}>
<Steps size="large" current={1}>
<Step title="Register" icon={<Icon type="solution" />} />
<Step title="Verify Email" icon={<Icon type="mail" />} />
</Steps>
{id && input["password"] ?
<Alert
style={{ marginTop: '24px' }}
message={
<div>
<span style={{marginRight: '10px'}}>验证邮件已发送,请查收~</span>
<Tag color="blue" onClick={this.onReSend}>重发</Tag>
<Tag color="orange" onClick={() => this.setState({ isChangeEmail: true })}>
修改邮箱
</Tag>
</div>
}
type="warning"
showIcon
/>
:
<Alert
style={{ marginTop: '24px' }}
message={
<div>
<span style={{marginRight: '10px'}}>您尚未登录,请先登录</span>
<Tag color="blue" onClick={ () => dispatch(routerRedux.replace("/signin"))}>登录</Tag>
</div>
}
type="warning"
showIcon
/>
}
{
this.state.isChangeEmail &&
<Form onSubmit={this.onSubmit} className="login-form" style={{ marginTop: '24px' }}>
<FormItem {...emailProps.fromItem}>
{getFieldDecorator('email', { ...emailProps.decorator })(
<Input
{...emailProps.input}
onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })} />
)}
</FormItem>
<FormItem>
<SubmitButton disabled={isEmailExists} />
</FormItem>
</Form>
}
</Spin>
</div>
);
}
}
function mapStateToProps(state, props) {
const {
user: { data } ,
auth: { input, isEmailExists, checkEmail }
} = state
const loading = state.loading.global || false
return {
input,
data,
loading,
checkEmail,
isEmailExists,
};
}
const WrapperVerify = Form.create()(Verify);
export default connect(mapStateToProps)(WrapperVerify);
...@@ -1708,6 +1708,12 @@ duplexer@^0.1.1: ...@@ -1708,6 +1708,12 @@ duplexer@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1"
dva-loading@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/dva-loading/-/dva-loading-0.2.1.tgz#fad76b8eeb28c3663a2ee1874cc118702940c63c"
dependencies:
babel-runtime "^6.11.6"
dva@^1.2.1: dva@^1.2.1:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/dva/-/dva-1.2.1.tgz#b9e78a4f1812b2230134d1bb7baadd1af3630138" resolved "https://registry.yarnpkg.com/dva/-/dva-1.2.1.tgz#b9e78a4f1812b2230134d1bb7baadd1af3630138"
...@@ -4312,6 +4318,13 @@ rc-progress@~2.0.1: ...@@ -4312,6 +4318,13 @@ rc-progress@~2.0.1:
version "2.0.6" version "2.0.6"
resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.0.6.tgz#799af503904330d35184ab00d61ebfcbc005c486" resolved "https://registry.yarnpkg.com/rc-progress/-/rc-progress-2.0.6.tgz#799af503904330d35184ab00d61ebfcbc005c486"
rc-queue-anim@^0.13.3:
version "0.13.3"
resolved "https://registry.yarnpkg.com/rc-queue-anim/-/rc-queue-anim-0.13.3.tgz#12bfa0d36764154bd52671dcc8d213ebedd5f5fb"
dependencies:
babel-runtime "6.x"
velocity-animate "~1.3.1"
rc-radio@~2.0.0: rc-radio@~2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/rc-radio/-/rc-radio-2.0.0.tgz#357b2da4d46564784b85d4bb5f0edf6c207155b3" resolved "https://registry.yarnpkg.com/rc-radio/-/rc-radio-2.0.0.tgz#357b2da4d46564784b85d4bb5f0edf6c207155b3"
...@@ -4462,6 +4475,13 @@ rc@^1.1.7: ...@@ -4462,6 +4475,13 @@ rc@^1.1.7:
minimist "^1.2.0" minimist "^1.2.0"
strip-json-comments "~2.0.1" strip-json-comments "~2.0.1"
react-addons-transition-group@^15.4.2:
version "15.4.2"
resolved "https://registry.yarnpkg.com/react-addons-transition-group/-/react-addons-transition-group-15.4.2.tgz#4c42fa1c2ce024acab2924316c0f11268ded1af3"
dependencies:
fbjs "^0.8.4"
object-assign "^4.1.0"
react-dev-utils@^0.4.2: react-dev-utils@^0.4.2:
version "0.4.2" version "0.4.2"
resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-0.4.2.tgz#ba6fae581fe945a2fc402e9b27c71fda4f62f6a1" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-0.4.2.tgz#ba6fae581fe945a2fc402e9b27c71fda4f62f6a1"
...@@ -5411,6 +5431,10 @@ vary@~1.1.0: ...@@ -5411,6 +5431,10 @@ vary@~1.1.0:
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.1.tgz#67535ebb694c1d52257457984665323f587e8d37"
velocity-animate@~1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/velocity-animate/-/velocity-animate-1.3.2.tgz#eb90d4ddb5f818c35937380b4b7df59934a26c3b"
vendors@^1.0.0: vendors@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22" resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.1.tgz#37ad73c8ee417fb3d580e785312307d274847f22"
......
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