Prevent showing contribution instructions for canceled / expired proposals (#334)
This commit is contained in:
parent
500175f5d2
commit
e160380daa
|
@ -517,12 +517,13 @@ class Proposal(db.Model):
|
||||||
'support_url': make_url('/contact'),
|
'support_url': make_url('/contact'),
|
||||||
})
|
})
|
||||||
for c in self.contributions:
|
for c in self.contributions:
|
||||||
send_email(c.user.email_address, 'contribution_proposal_canceled', {
|
if c.user:
|
||||||
'contribution': c,
|
send_email(c.user.email_address, 'contribution_proposal_canceled', {
|
||||||
'proposal': self,
|
'contribution': c,
|
||||||
'refund_address': c.user.settings.refund_address,
|
'proposal': self,
|
||||||
'account_settings_url': make_url('/profile/settings?tab=account')
|
'refund_address': c.user.settings.refund_address,
|
||||||
})
|
'account_settings_url': make_url('/profile/settings?tab=account')
|
||||||
|
})
|
||||||
|
|
||||||
@hybrid_property
|
@hybrid_property
|
||||||
def contributed(self):
|
def contributed(self):
|
||||||
|
|
|
@ -461,15 +461,15 @@ def get_proposal_contributions(proposal_id):
|
||||||
@blueprint.route("/<proposal_id>/contributions/<contribution_id>", methods=["GET"])
|
@blueprint.route("/<proposal_id>/contributions/<contribution_id>", methods=["GET"])
|
||||||
def get_proposal_contribution(proposal_id, contribution_id):
|
def get_proposal_contribution(proposal_id, contribution_id):
|
||||||
proposal = Proposal.query.filter_by(id=proposal_id).first()
|
proposal = Proposal.query.filter_by(id=proposal_id).first()
|
||||||
if proposal:
|
if not proposal:
|
||||||
contribution = ProposalContribution.query.filter_by(id=contribution_id).first()
|
|
||||||
if contribution:
|
|
||||||
return proposal_contribution_schema.dump(contribution)
|
|
||||||
else:
|
|
||||||
return {"message": "No contribution matching id"}
|
|
||||||
else:
|
|
||||||
return {"message": "No proposal matching id"}, 404
|
return {"message": "No proposal matching id"}, 404
|
||||||
|
|
||||||
|
contribution = ProposalContribution.query.filter_by(id=contribution_id).first()
|
||||||
|
if not contribution:
|
||||||
|
return {"message": "No contribution matching id"}, 404
|
||||||
|
|
||||||
|
return proposal_contribution_schema.dump(contribution)
|
||||||
|
|
||||||
|
|
||||||
@blueprint.route("/<proposal_id>/contributions", methods=["POST"])
|
@blueprint.route("/<proposal_id>/contributions", methods=["POST"])
|
||||||
# TODO add gaurd (minimum, maximum)
|
# TODO add gaurd (minimum, maximum)
|
||||||
|
|
|
@ -8,6 +8,7 @@ import { formatTxExplorerUrl } from 'utils/formatters';
|
||||||
import { deleteContribution } from 'modules/users/actions';
|
import { deleteContribution } from 'modules/users/actions';
|
||||||
import { UserContribution } from 'types';
|
import { UserContribution } from 'types';
|
||||||
import './ProfileContribution.less';
|
import './ProfileContribution.less';
|
||||||
|
import { PROPOSAL_STAGE } from 'api/constants';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
userId: number;
|
userId: number;
|
||||||
|
@ -26,7 +27,10 @@ class ProfileContribution extends React.Component<Props> {
|
||||||
const { contribution } = this.props;
|
const { contribution } = this.props;
|
||||||
const { proposal } = contribution;
|
const { proposal } = contribution;
|
||||||
const isConfirmed = contribution.status === 'CONFIRMED';
|
const isConfirmed = contribution.status === 'CONFIRMED';
|
||||||
const isExpired = !isConfirmed && contribution.dateCreated < Date.now() / 1000 - ONE_DAY;
|
const isExpired =
|
||||||
|
(!isConfirmed && contribution.dateCreated < Date.now() / 1000 - ONE_DAY) ||
|
||||||
|
(proposal.stage === PROPOSAL_STAGE.CANCELED ||
|
||||||
|
proposal.stage === PROPOSAL_STAGE.FAILED);
|
||||||
|
|
||||||
let tag;
|
let tag;
|
||||||
let actions: React.ReactNode;
|
let actions: React.ReactNode;
|
||||||
|
@ -43,15 +47,14 @@ class ProfileContribution extends React.Component<Props> {
|
||||||
} else if (isExpired) {
|
} else if (isExpired) {
|
||||||
tag = <Tag color="red">Expired</Tag>;
|
tag = <Tag color="red">Expired</Tag>;
|
||||||
// TODO: Link to support
|
// TODO: Link to support
|
||||||
actions = <>
|
actions = (
|
||||||
<Popconfirm
|
<>
|
||||||
title="Are you sure?"
|
<Popconfirm title="Are you sure?" onConfirm={this.deleteContribution}>
|
||||||
onConfirm={this.deleteContribution}
|
<a>Delete</a>
|
||||||
>
|
</Popconfirm>
|
||||||
<a>Delete</a>
|
<Link to="/support">Contact support</Link>
|
||||||
</Popconfirm>
|
</>
|
||||||
<Link to="/support">Contact support</Link>
|
);
|
||||||
</>;
|
|
||||||
} else {
|
} else {
|
||||||
tag = <Tag color="orange">Pending</Tag>;
|
tag = <Tag color="orange">Pending</Tag>;
|
||||||
actions = (
|
actions = (
|
||||||
|
@ -76,9 +79,7 @@ class ProfileContribution extends React.Component<Props> {
|
||||||
<div className="ProfileContribution-state-amount">
|
<div className="ProfileContribution-state-amount">
|
||||||
+<UnitDisplay value={contribution.amount} symbol="ZEC" />
|
+<UnitDisplay value={contribution.amount} symbol="ZEC" />
|
||||||
</div>
|
</div>
|
||||||
<div className="ProfileContribution-state-actions">
|
<div className="ProfileContribution-state-actions">{actions}</div>
|
||||||
{actions}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -89,6 +90,9 @@ class ProfileContribution extends React.Component<Props> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect<{}, DispatchProps, OwnProps, {}>(undefined, {
|
export default connect<{}, DispatchProps, OwnProps, {}>(
|
||||||
deleteContribution,
|
undefined,
|
||||||
})(ProfileContribution);
|
{
|
||||||
|
deleteContribution,
|
||||||
|
},
|
||||||
|
)(ProfileContribution);
|
||||||
|
|
Loading…
Reference in New Issue