zcash-grant-system/frontend/client/components/RFP/index.tsx

169 lines
4.8 KiB
TypeScript
Raw Normal View History

import React from 'react';
import moment from 'moment';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
2020-07-24 12:23:45 -07:00
import { Icon, Tag } from 'antd';
import ExceptionPage from 'components/ExceptionPage';
import { fetchRfp } from 'modules/rfps/actions';
import { getRfp } from 'modules/rfps/selectors';
import { RFP } from 'types';
import { AppState } from 'store/reducers';
import Loader from 'components/Loader';
import Markdown from 'components/Markdown';
import ProposalCard from 'components/Proposals/ProposalCard';
2019-02-08 11:02:34 -08:00
import UnitDisplay from 'components/UnitDisplay';
import HeaderDetails from 'components/HeaderDetails';
import Like from 'components/Like';
import { RFP_STATUS } from 'api/constants';
import { formatUsd } from 'utils/formatters';
import './index.less';
interface OwnProps {
rfpId: number;
}
interface StateProps {
rfp: RFP | undefined;
isFetchingRfps: AppState['rfps']['isFetchingRfps'];
fetchRfpsError: AppState['rfps']['fetchRfpsError'];
}
interface DispatchProps {
fetchRfp: typeof fetchRfp;
}
type Props = OwnProps & StateProps & DispatchProps;
CCRs (#86) * CCRs API / Models boilerplate * start on frontend * backendy things * Create CCR redux module, integrate API endpoints, create types * Fix/Cleanup API * Wire up CreateRequestDraftList * bounty->target * Add 'Create Request Flow' MVP * cleanup * Tweak filenames * Simplify migrations * fix migrations * CCR Staking MVP * tslint * Get Pending Requests into Profile * Remove staking requirement * more staking related removals * MVP Admin integration * Make RFP when CCR is accepted * Add pagination to CCRs in Admin Improve styles for Proposals * Hookup notifications Adjust copy * Simplify ccr->rfp relationship Add admin approval email Fixup copy * Show Message on RFP Detail Make Header CTAs change based on draft status Adjust proposal card style * Bugfix: Show header for non signed in users * Add 'create a request' to intro * Profile Created CCRs RFP CCR attribution * ignore * CCR Price in USD (#85) * init profile tipjar backend * init profile tipjar frontend * fix lint * implement tip jar block * fix wrapping, hide tip block on self * init backend proposal tipjar * init frontend proposal tipjar * add hide title, fix bug * uncomment rate limit * rename vars, use null check * allow address and view key to be unset * add api tests * fix tsc errors * fix lint * fix CopyInput styling * fix migrations * hide tipping in proposal if address not set * add tip address to create flow * redesign campaign block * fix typo * init backend changes * init admin changes * init frontend changes * fix backend tests * update campaign block * be - init rfp usd changes * admin - init rfp usd changes * fe - fully adapt api util functions to usd * fe - init rfp usd changes * adapt profile created to usd * misc usd changes * add tip jar to dedicated card * fix tipjar bug * use zf light logo * switch to zf grants logo * hide profile tip jar if address not set * add comment, run prettier * conditionally add info icon and tooltip to funding line * admin - disallow decimals in RFPs * fe - cover usd string edge case * add Usd as rfp bounty type * fix migration order * fix email bug * adapt CCRs to USD * implement CCR preview * fix tsc * Copy Updates and UX Tweaks (#87) * Add default structure to proposal content * Landing page copy * Hide contributors tab for v2 proposals * Minor UX tweaks for Liking/Following/Tipping * Copy for Tipping Tooltip, proposal explainer for review, and milestone day estimate notice. * Fix header styles bug and remove commented out styles. * Revert "like" / "unfollow" hyphenication * Comment out unused tests related to staking Increase PROPOSAL_TARGET_MAX in .env.example * Comment out ccr approval email send until ready * Adjust styles, copy. * fix proposal prune test (#88) * fix USD display in preview, fix non-unique key (#90) * Pre-stepper explainer for CCRs. * Tweak styles * Default content for CCRs * fix tsc * CCR approval and rejection emails * add back admin_approval_ccr email templates * Link ccr author name to profile in RFPs * copy tweaks * copy tweak * hookup mangle user command * Fix/add endif in jinja * fix tests * review * fix review
2019-12-05 17:01:02 -08:00
export class RFPDetail extends React.Component<Props> {
componentDidMount() {
this.props.fetchRfp(this.props.rfpId);
}
render() {
const { rfp, isFetchingRfps } = this.props;
// Optimistically render rfp if we have it, but are updating it
if (!rfp) {
if (isFetchingRfps) {
return <Loader size="large" />;
} else {
return <ExceptionPage code="404" desc="No request could be found" />;
}
}
const isLive = rfp.status === RFP_STATUS.LIVE;
2019-02-18 10:08:20 -08:00
const tags = [];
if (rfp.matching) {
tags.push(
<Tag key="matching" color="#1890ff">
x2 matching
</Tag>,
);
}
if (rfp.bounty) {
if (rfp.isVersionTwo) {
tags.push(
<Tag key="bounty" color="#CF8A00">
{formatUsd(rfp.bounty.toString(10))} bounty
</Tag>,
);
} else {
tags.push(
<Tag key="bounty" color="#CF8A00">
<UnitDisplay value={rfp.bounty} symbol="ZEC" /> bounty
</Tag>,
);
}
2019-02-18 10:08:20 -08:00
}
if (!isLive) {
tags.push(
<Tag key="closed" color="#f5222d">
Closed
</Tag>,
);
}
return (
<div className="RFPDetail">
<HeaderDetails title={rfp.title} description={rfp.brief} />
<div className="RFPDetail-top">
<Link className="RFPDetail-top-back" to="/requests">
<Icon type="arrow-left" /> Back to Requests
</Link>
2019-02-18 10:08:20 -08:00
<div className="RFPDetail-top-date">
2019-02-08 11:02:34 -08:00
Opened {moment(rfp.dateOpened * 1000).format('LL')}
</div>
<Like rfp={rfp} />
</div>
2019-02-18 10:08:20 -08:00
<h1 className="RFPDetail-title">{rfp.title}</h1>
2019-02-18 10:08:20 -08:00
<div className="RFPDetail-tags">{tags}</div>
<p className="RFPDetail-brief">{rfp.brief}</p>
<Markdown className="RFPDetail-content" source={rfp.content} />
2019-02-08 11:02:34 -08:00
<div className="RFPDetail-rules">
<ul>
{rfp.bounty &&
rfp.isVersionTwo && (
<li>
Accepted proposals will be funded up to{' '}
<strong>{formatUsd(rfp.bounty.toString(10))}</strong> in ZEC
</li>
)}
{rfp.bounty &&
!rfp.isVersionTwo && (
<li>
Accepted proposals will be funded up to{' '}
<strong>
<UnitDisplay value={rfp.bounty} symbol="ZEC" />
</strong>
</li>
)}
2019-02-08 11:02:34 -08:00
{rfp.matching && (
<li>
Contributions will have their <strong>funding matched</strong> by the
Zcash Foundation
2019-02-08 11:02:34 -08:00
</li>
)}
{rfp.dateCloses && (
<li>
Proposal submissions end {moment(rfp.dateCloses * 1000).format('LL')}
</li>
)}
CCRs (#86) * CCRs API / Models boilerplate * start on frontend * backendy things * Create CCR redux module, integrate API endpoints, create types * Fix/Cleanup API * Wire up CreateRequestDraftList * bounty->target * Add 'Create Request Flow' MVP * cleanup * Tweak filenames * Simplify migrations * fix migrations * CCR Staking MVP * tslint * Get Pending Requests into Profile * Remove staking requirement * more staking related removals * MVP Admin integration * Make RFP when CCR is accepted * Add pagination to CCRs in Admin Improve styles for Proposals * Hookup notifications Adjust copy * Simplify ccr->rfp relationship Add admin approval email Fixup copy * Show Message on RFP Detail Make Header CTAs change based on draft status Adjust proposal card style * Bugfix: Show header for non signed in users * Add 'create a request' to intro * Profile Created CCRs RFP CCR attribution * ignore * CCR Price in USD (#85) * init profile tipjar backend * init profile tipjar frontend * fix lint * implement tip jar block * fix wrapping, hide tip block on self * init backend proposal tipjar * init frontend proposal tipjar * add hide title, fix bug * uncomment rate limit * rename vars, use null check * allow address and view key to be unset * add api tests * fix tsc errors * fix lint * fix CopyInput styling * fix migrations * hide tipping in proposal if address not set * add tip address to create flow * redesign campaign block * fix typo * init backend changes * init admin changes * init frontend changes * fix backend tests * update campaign block * be - init rfp usd changes * admin - init rfp usd changes * fe - fully adapt api util functions to usd * fe - init rfp usd changes * adapt profile created to usd * misc usd changes * add tip jar to dedicated card * fix tipjar bug * use zf light logo * switch to zf grants logo * hide profile tip jar if address not set * add comment, run prettier * conditionally add info icon and tooltip to funding line * admin - disallow decimals in RFPs * fe - cover usd string edge case * add Usd as rfp bounty type * fix migration order * fix email bug * adapt CCRs to USD * implement CCR preview * fix tsc * Copy Updates and UX Tweaks (#87) * Add default structure to proposal content * Landing page copy * Hide contributors tab for v2 proposals * Minor UX tweaks for Liking/Following/Tipping * Copy for Tipping Tooltip, proposal explainer for review, and milestone day estimate notice. * Fix header styles bug and remove commented out styles. * Revert "like" / "unfollow" hyphenication * Comment out unused tests related to staking Increase PROPOSAL_TARGET_MAX in .env.example * Comment out ccr approval email send until ready * Adjust styles, copy. * fix proposal prune test (#88) * fix USD display in preview, fix non-unique key (#90) * Pre-stepper explainer for CCRs. * Tweak styles * Default content for CCRs * fix tsc * CCR approval and rejection emails * add back admin_approval_ccr email templates * Link ccr author name to profile in RFPs * copy tweaks * copy tweak * hookup mangle user command * Fix/add endif in jinja * fix tests * review * fix review
2019-12-05 17:01:02 -08:00
{rfp.ccr && (
<li>
Submitted by{' '}
<Link to={`/profile/${rfp.ccr.author.userid}`}>
{rfp.ccr.author.displayName}
</Link>
</li>
)}
2019-02-08 11:02:34 -08:00
</ul>
</div>
{!!rfp.acceptedProposals.length && (
<div className="RFPDetail-proposals">
<h2 className="RFPDetail-proposals-title">Accepted Proposals</h2>
{rfp.acceptedProposals.map(p => (
<ProposalCard key={p.proposalId} {...p} />
))}
</div>
)}
</div>
);
}
}
export default connect<StateProps, DispatchProps, OwnProps, AppState>(
(state, ownProps) => ({
rfp: getRfp(state, ownProps.rfpId),
isFetchingRfps: state.rfps.isFetchingRfps,
fetchRfpsError: state.rfps.fetchRfpsError,
}),
{ fetchRfp },
)(RFPDetail);