2019-02-06 14:37:45 -08:00
|
|
|
import React from 'react';
|
|
|
|
import { Link } from 'react-router-dom';
|
2019-02-13 08:54:46 -08:00
|
|
|
import moment from 'moment';
|
|
|
|
import { UserProposalArbiter, PROPOSAL_ARBITER_STATUS, MILESTONE_STAGE } from 'types';
|
2019-02-06 14:37:45 -08:00
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { AppState } from 'store/reducers';
|
2019-02-09 19:03:19 -08:00
|
|
|
import { updateUserArbiter } from 'api/api';
|
|
|
|
import { usersActions } from 'modules/users';
|
|
|
|
import { Button, Popconfirm, message } from 'antd';
|
2019-02-06 14:37:45 -08:00
|
|
|
import './ProfileArbitrated.less';
|
|
|
|
|
2019-02-09 19:03:19 -08:00
|
|
|
const PAS = PROPOSAL_ARBITER_STATUS;
|
|
|
|
|
2019-02-06 14:37:45 -08:00
|
|
|
interface OwnProps {
|
2019-02-09 19:03:19 -08:00
|
|
|
arbiter: UserProposalArbiter;
|
2019-02-06 14:37:45 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
interface StateProps {
|
|
|
|
user: AppState['auth']['user'];
|
|
|
|
}
|
|
|
|
|
2019-02-09 19:03:19 -08:00
|
|
|
interface DispatchProps {
|
|
|
|
fetchUser: typeof usersActions['fetchUser'];
|
|
|
|
}
|
|
|
|
|
|
|
|
type Props = OwnProps & StateProps & DispatchProps;
|
2019-02-06 14:37:45 -08:00
|
|
|
|
|
|
|
class ProfileArbitrated extends React.Component<Props, {}> {
|
|
|
|
render() {
|
2019-02-09 19:03:19 -08:00
|
|
|
const { status } = this.props.arbiter;
|
2019-02-13 08:54:46 -08:00
|
|
|
const { title, proposalId, currentMilestone } = this.props.arbiter.proposal;
|
|
|
|
const isMsPayoutReq =
|
|
|
|
currentMilestone && currentMilestone.stage === MILESTONE_STAGE.REQUESTED;
|
|
|
|
const msTitle = currentMilestone && currentMilestone.title;
|
2019-02-09 19:03:19 -08:00
|
|
|
|
|
|
|
const info = {
|
|
|
|
[PAS.MISSING]: <>{/* nada */}</>,
|
|
|
|
[PAS.NOMINATED]: <>You have been nominated to be the arbiter for this proposal.</>,
|
|
|
|
[PAS.ACCEPTED]: (
|
|
|
|
<>
|
2019-02-13 08:54:46 -08:00
|
|
|
{isMsPayoutReq && (
|
|
|
|
<>
|
|
|
|
The team has requested payout for <b>{msTitle}</b>{' '}
|
|
|
|
{moment((currentMilestone!.dateRequested || 0) * 1000).fromNow()}. Please
|
|
|
|
click the button to proceed.
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
{!isMsPayoutReq && (
|
|
|
|
<>
|
|
|
|
As arbiter of this proposal, you are responsible for reviewing milestone
|
|
|
|
payout requests.{' '}
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
<br />
|
|
|
|
<br />
|
|
|
|
You may{' '}
|
2019-02-09 19:03:19 -08:00
|
|
|
<Popconfirm
|
|
|
|
title="Stop acting as arbiter?"
|
|
|
|
onConfirm={() => this.acceptArbiter(false)}
|
|
|
|
>
|
|
|
|
<a href="#">opt out</a>
|
|
|
|
</Popconfirm>{' '}
|
|
|
|
at any time.
|
|
|
|
</>
|
|
|
|
),
|
|
|
|
};
|
|
|
|
|
|
|
|
const actions = {
|
|
|
|
[PAS.MISSING]: <>{/* nada */}</>,
|
|
|
|
[PAS.NOMINATED]: (
|
|
|
|
<>
|
|
|
|
<Button onClick={() => this.acceptArbiter(true)} type="primary">
|
|
|
|
Accept
|
|
|
|
</Button>
|
|
|
|
<Button onClick={() => this.acceptArbiter(false)}>Reject</Button>
|
|
|
|
</>
|
|
|
|
),
|
2019-02-13 08:54:46 -08:00
|
|
|
[PAS.ACCEPTED]: (
|
|
|
|
<>
|
|
|
|
{isMsPayoutReq && (
|
|
|
|
<Link to={`/proposals/${proposalId}?tab=milestones`}>
|
|
|
|
<Button type="primary">Review Milestone</Button>
|
|
|
|
</Link>
|
|
|
|
)}
|
|
|
|
</>
|
|
|
|
),
|
2019-02-09 19:03:19 -08:00
|
|
|
};
|
2019-02-06 14:37:45 -08:00
|
|
|
|
|
|
|
return (
|
|
|
|
<div className="ProfileArbitrated">
|
|
|
|
<div className="ProfileArbitrated-block">
|
|
|
|
<Link to={`/proposals/${proposalId}`} className="ProfileArbitrated-title">
|
|
|
|
{title}
|
|
|
|
</Link>
|
2019-02-09 19:03:19 -08:00
|
|
|
<div className={`ProfileArbitrated-info`}>{info[status]}</div>
|
2019-02-06 14:37:45 -08:00
|
|
|
</div>
|
2019-02-09 19:03:19 -08:00
|
|
|
<div className="ProfileArbitrated-block is-actions">{actions[status]}</div>
|
2019-02-06 14:37:45 -08:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2019-02-09 19:03:19 -08:00
|
|
|
|
|
|
|
private acceptArbiter = async (isAccept: boolean) => {
|
|
|
|
const {
|
|
|
|
arbiter: { proposal },
|
|
|
|
user,
|
|
|
|
fetchUser,
|
|
|
|
} = this.props;
|
|
|
|
await updateUserArbiter(user!.userid, proposal.proposalId, isAccept);
|
|
|
|
message.success(isAccept ? 'Accepted arbiter position' : 'Rejected arbiter position');
|
|
|
|
// refetch all the user data (includes the arbiter proposals)
|
|
|
|
await fetchUser(String(user!.userid));
|
|
|
|
};
|
2019-02-06 14:37:45 -08:00
|
|
|
}
|
|
|
|
|
2019-02-09 19:03:19 -08:00
|
|
|
export default connect<StateProps, DispatchProps, OwnProps, AppState>(
|
|
|
|
state => ({
|
|
|
|
user: state.auth.user,
|
|
|
|
}),
|
|
|
|
{ fetchUser: usersActions.fetchUser },
|
|
|
|
)(ProfileArbitrated);
|