Merge branch 'develop' into comment-placeholder
This commit is contained in:
commit
c4b7e281a5
|
@ -19,6 +19,7 @@ from grant.utils.misc import is_email, make_url, from_zat
|
|||
from grant.utils.enums import ProposalStatus, ContributionStatus
|
||||
from grant.utils import pagination
|
||||
from sqlalchemy import or_
|
||||
from datetime import datetime
|
||||
|
||||
from .models import (
|
||||
Proposal,
|
||||
|
@ -216,7 +217,7 @@ def update_proposal(milestones, proposal_id, **kwargs):
|
|||
m = Milestone(
|
||||
title=mdata["title"],
|
||||
content=mdata["content"],
|
||||
date_estimated=parse(mdata["dateEstimated"]),
|
||||
date_estimated=datetime.fromtimestamp(mdata["dateEstimated"]),
|
||||
payout_percent=str(mdata["payoutPercent"]),
|
||||
immediate_payout=mdata["immediatePayout"],
|
||||
proposal_id=g.current_proposal.id
|
||||
|
|
|
@ -156,10 +156,7 @@ class User(db.Model, UserMixin):
|
|||
db.session.commit()
|
||||
|
||||
if _send_email:
|
||||
send_email(user.email_address, 'signup', {
|
||||
'display_name': user.display_name,
|
||||
'confirm_url': make_url(f'/email/verify?code={ev.code}')
|
||||
})
|
||||
user.send_verification_email()
|
||||
|
||||
return user
|
||||
|
||||
|
@ -212,6 +209,12 @@ class User(db.Model, UserMixin):
|
|||
def login(self):
|
||||
login_user(self)
|
||||
|
||||
def send_verification_email(self):
|
||||
send_email(self.email_address, 'signup', {
|
||||
'display_name': self.display_name,
|
||||
'confirm_url': make_url(f'/email/verify?code={self.email_verification.code}')
|
||||
})
|
||||
|
||||
def send_recovery_email(self):
|
||||
existing = self.email_recovery
|
||||
if existing:
|
||||
|
|
|
@ -170,11 +170,18 @@ def update_user_password(current_password, password):
|
|||
def update_user_email(email, password):
|
||||
if not g.current_user.check_password(password):
|
||||
return {"message": "Password is incorrect"}, 403
|
||||
print('set_email')
|
||||
g.current_user.set_email(email)
|
||||
return None, 200
|
||||
|
||||
|
||||
@blueprint.route("/me/resend-verification", methods=["PUT"])
|
||||
@requires_auth
|
||||
@endpoint.api()
|
||||
def resend_email_verification():
|
||||
g.current_user.send_verification_email()
|
||||
return None, 200
|
||||
|
||||
|
||||
@blueprint.route("/logout", methods=["POST"])
|
||||
@requires_auth
|
||||
@endpoint.api()
|
||||
|
|
|
@ -31,7 +31,7 @@ milestones = [
|
|||
{
|
||||
"title": "All the money straightaway",
|
||||
"content": "cool stuff with it",
|
||||
"dateEstimated": "Fri, 30 Nov 2018 01:42:23 GMT",
|
||||
"dateEstimated": 1549505307,
|
||||
"payoutPercent": "100",
|
||||
"immediatePayout": False
|
||||
}
|
||||
|
|
|
@ -294,3 +294,7 @@ export function getRFP(rfpId: number | string): Promise<{ data: RFP }> {
|
|||
return res;
|
||||
});
|
||||
}
|
||||
|
||||
export function resendEmailVerification(): Promise<{ data: void }> {
|
||||
return axios.put(`/api/v1/users/me/resend-verification`);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
.AccountSettings {
|
||||
&-form {
|
||||
&-resend {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
& > .ant-form-item {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Form, Input, Button, Alert } from 'antd';
|
||||
import { Form, Input, Button, Alert, message } from 'antd';
|
||||
import { FormComponentProps } from 'antd/lib/form';
|
||||
import { updateUserEmail } from 'api/api';
|
||||
import Loader from 'components/Loader';
|
||||
import { updateUserEmail, resendEmailVerification } from 'api/api';
|
||||
import { AppState } from 'store/reducers';
|
||||
import './Account.less';
|
||||
|
||||
interface StateProps {
|
||||
email: string;
|
||||
emailVerified: boolean;
|
||||
}
|
||||
|
||||
type Props = FormComponentProps & StateProps;
|
||||
|
@ -17,6 +19,8 @@ const STATE = {
|
|||
emailChangePending: false,
|
||||
emailChangeSuccess: false,
|
||||
emailChangeError: '',
|
||||
isResendingVerification: false,
|
||||
hasResentVerification: false,
|
||||
};
|
||||
|
||||
type State = typeof STATE;
|
||||
|
@ -25,12 +29,14 @@ class AccountSettings extends React.Component<Props, State> {
|
|||
state: State = { ...STATE };
|
||||
|
||||
render() {
|
||||
const { email, form } = this.props;
|
||||
const { email, emailVerified, form } = this.props;
|
||||
const {
|
||||
emailChangeError,
|
||||
emailChangePending,
|
||||
emailChangeSuccess,
|
||||
newEmail,
|
||||
isResendingVerification,
|
||||
hasResentVerification,
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
|
@ -40,6 +46,36 @@ class AccountSettings extends React.Component<Props, State> {
|
|||
onSubmit={this.handleSubmit}
|
||||
layout="vertical"
|
||||
>
|
||||
{!emailVerified &&
|
||||
!hasResentVerification && (
|
||||
<Alert
|
||||
showIcon
|
||||
className="AccountSettings-form-resend"
|
||||
type="warning"
|
||||
message="Your email has not been verified"
|
||||
description={
|
||||
<>
|
||||
You should have a verification in your inbox. If you can't find it,
|
||||
check your spam folder. Still don't see it?{' '}
|
||||
<a onClick={this.resendEmailVerification}>Click here to resend</a>.
|
||||
{isResendingVerification && <Loader overlay />}
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{!emailVerified &&
|
||||
hasResentVerification && (
|
||||
<Alert
|
||||
showIcon
|
||||
className="AccountSettings-form-resend"
|
||||
type="success"
|
||||
message="Verification has been sent"
|
||||
description={`
|
||||
It should be in your inbox shortly. If you don’t see it soon,
|
||||
check your spam folder or contact support for help.
|
||||
`}
|
||||
/>
|
||||
)}
|
||||
<Form.Item label="Email">
|
||||
{form.getFieldDecorator('email', {
|
||||
initialValue: newEmail || email,
|
||||
|
@ -139,10 +175,25 @@ class AccountSettings extends React.Component<Props, State> {
|
|||
}
|
||||
});
|
||||
};
|
||||
|
||||
private resendEmailVerification = async () => {
|
||||
if (this.state.isResendingVerification) {
|
||||
return;
|
||||
}
|
||||
this.setState({ isResendingVerification: true });
|
||||
try {
|
||||
await resendEmailVerification();
|
||||
this.setState({ hasResentVerification: true });
|
||||
} catch (err) {
|
||||
message.error(err.message || err.toString());
|
||||
}
|
||||
this.setState({ isResendingVerification: false });
|
||||
};
|
||||
}
|
||||
|
||||
const FormWrappedAccountSettings = Form.create()(AccountSettings);
|
||||
|
||||
export default connect<StateProps, {}, {}, AppState>(state => ({
|
||||
email: state.auth.user ? state.auth.user.emailAddress || '' : '',
|
||||
emailVerified: !!state.auth.user && !!state.auth.user.emailVerified,
|
||||
}))(FormWrappedAccountSettings);
|
||||
|
|
Loading…
Reference in New Issue