ensure proposals can only be submitted when KYC is accepted. Setup KYC info modal
This commit is contained in:
parent
d6c7119dd0
commit
a36861d063
|
@ -0,0 +1,34 @@
|
|||
|
||||
.KYCModal {
|
||||
&.ant-modal {
|
||||
width: 50vw !important;
|
||||
|
||||
}
|
||||
|
||||
& .ant-modal-body {
|
||||
padding-right: 2.5vw;
|
||||
padding-left: 2.5vw;
|
||||
}
|
||||
|
||||
& ::marker {
|
||||
content: counters(list-item, '.') ':';
|
||||
color: #CF8A00;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& ol ol {
|
||||
padding-left: 60px;
|
||||
}
|
||||
|
||||
& li {
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
margin-bottom: 5px;
|
||||
|
||||
}
|
||||
|
||||
& li li {
|
||||
counter-reset: section
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +1,18 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Input, Form, Alert, Popconfirm, message, Radio } from 'antd';
|
||||
import { Alert, Form, Input, message, Modal, Popconfirm, Radio } from 'antd';
|
||||
import { RadioChangeEvent } from 'antd/lib/radio';
|
||||
import { ProposalDraft, RFP } from 'types';
|
||||
import { getCreateErrors } from 'modules/create/utils';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { unlinkProposalRFP } from 'modules/create/actions';
|
||||
import { AppState } from 'store/reducers';
|
||||
import './Basics.less';
|
||||
|
||||
interface OwnProps {
|
||||
proposalId: number;
|
||||
initialState?: Partial<State>;
|
||||
|
||||
updateForm(form: Partial<ProposalDraft>): void;
|
||||
}
|
||||
|
||||
|
@ -30,6 +32,7 @@ interface State extends Partial<ProposalDraft> {
|
|||
brief: string;
|
||||
target: string;
|
||||
rfp?: RFP;
|
||||
visible: boolean
|
||||
}
|
||||
|
||||
class CreateFlowBasics extends React.Component<Props, State> {
|
||||
|
@ -39,10 +42,29 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
title: '',
|
||||
brief: '',
|
||||
target: '',
|
||||
visible: false,
|
||||
...(props.initialState || {}),
|
||||
};
|
||||
}
|
||||
|
||||
showModal = () => {
|
||||
this.setState({
|
||||
visible: true,
|
||||
});
|
||||
};
|
||||
|
||||
handleOk = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = () => {
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps: Props) {
|
||||
const { unlinkProposalRFPError, isUnlinkingProposalRFP } = this.props;
|
||||
if (
|
||||
|
@ -72,21 +94,21 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
return (
|
||||
<Form layout="vertical" style={{ maxWidth: 600, margin: '0 auto' }}>
|
||||
<Form layout='vertical' style={{ maxWidth: 600, margin: '0 auto' }}>
|
||||
{rfp && (
|
||||
<Alert
|
||||
className="CreateFlow-rfpAlert"
|
||||
type="info"
|
||||
message="This proposal is linked to a request"
|
||||
className='CreateFlow-rfpAlert'
|
||||
type='info'
|
||||
message='This proposal is linked to a request'
|
||||
description={
|
||||
<>
|
||||
This proposal is for the open request{' '}
|
||||
<Link to={`/requests/${rfp.id}`} target="_blank">
|
||||
<Link to={`/requests/${rfp.id}`} target='_blank'>
|
||||
{rfp.title}
|
||||
</Link>
|
||||
. If you didn’t mean to do this, or want to unlink it,{' '}
|
||||
<Popconfirm
|
||||
title="Are you sure? This cannot be undone."
|
||||
title='Are you sure? This cannot be undone.'
|
||||
onConfirm={this.unlinkRfp}
|
||||
okButtonProps={{ loading: isUnlinkingProposalRFP }}
|
||||
>
|
||||
|
@ -100,9 +122,9 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
)}
|
||||
|
||||
<Alert
|
||||
className="CreateFlow-rfpAlert"
|
||||
type="warning"
|
||||
message="KYC (know your customer)"
|
||||
className='CreateFlow-rfpAlert'
|
||||
type='warning'
|
||||
message='KYC (know your customer)'
|
||||
description={
|
||||
<>
|
||||
<div>
|
||||
|
@ -110,12 +132,12 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
provide identifying information to the Zcash Foundation.
|
||||
<Radio.Group onChange={this.handleRfpOptIn}>
|
||||
<Radio value={true} checked={rfpOptIn && rfpOptIn === true}>
|
||||
<b>Yes</b>, I am willing to provide KYC information
|
||||
<b>Yes</b>, I am willing to provide KYC information as outlined by the <span
|
||||
onClick={() => this.showModal()} style={{ color: 'CF8A00', textDecoration: 'underline' }}>ZF KYC requirements</span>
|
||||
</Radio>
|
||||
<Radio value={false} checked={rfpOptIn !== null && rfpOptIn === false}>
|
||||
<b>No</b>, I do not wish to provide KYC information and understand my
|
||||
proposal may still be posted on ZF Grants, but I will not be eligible
|
||||
to funding from the Zcash Foundation.
|
||||
<b>No</b>, I do not wish to provide KYC information and understand I will not be able to submit my
|
||||
proposal.
|
||||
</Radio>
|
||||
</Radio.Group>
|
||||
</div>
|
||||
|
@ -123,16 +145,82 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
title='Know Your Customer (KYC) Compliance'
|
||||
visible={this.state.visible}
|
||||
onOk={this.handleOk}
|
||||
onCancel={this.handleCancel}
|
||||
className={'KYCModal'}
|
||||
>
|
||||
<ol>
|
||||
<li>To execute a transfer of funds, the Zcash Foundation is legally required to obtain the following
|
||||
information
|
||||
from you: [Privacy guarantee]
|
||||
<ol>
|
||||
<li>A photocopy of your state-issued identification (passport, driver's license, etc.)</li>
|
||||
|
||||
<li>A filled-out form <a href={'https://www.irs.gov/pub/irs-pdf/fw9.pdf'}>W-9</a> (if US taxpayer) or <a
|
||||
href={'https://www.irs.gov/pub/irs-pdf/fw8ben.pdf'}>W-8BEN</a> (if nonresident alien individual), or
|
||||
a <a href={'https://www.irs.gov/pub/irs-pdf/fw8bene.pdf'}>W-8BEN-E</a> (if foreign corporation)
|
||||
</li>
|
||||
|
||||
<li>The Foundation will run a Sanctions Screening and Fraud Monitoring on each recipient of its funds.
|
||||
As a condition of receiving the funds you represent to us, now and until the latter of the submission of a
|
||||
report on the status of the work covered by the proposal or the use of all of the funds, (i) that you are not
|
||||
in violation of any law relating to terrorism or money laundering (“Anti-Terrorism Laws”), including
|
||||
Executive Order No. 13224 on Terrorist Financing, effective September 24, 2001 (the “Executive Order”), and the
|
||||
Uniting and Strengthening America by Providing Appropriate Tools Required to Intercept and Obstruct
|
||||
Terrorism Act of 2001(Title III of P.L. No. 107-56) (known as the “PATRIOT Act”). (ii) neither you or any affiliated
|
||||
person or entity is a person that is listed in the annex to, or is otherwise subject to the provisions of,
|
||||
the Executive Order or a person that is named as a “specially designated national and blocked person” on
|
||||
the most current list published by the US Department of the Treasury, Office of Foreign Assets Control (“OFAC”) at its
|
||||
official website or any replacement website or other replacement official publication of such list;
|
||||
(iii) neither you or any affiliated person or entity is subject to blocking provisions or otherwise a target of
|
||||
sanctions imposed under any sanctions program administered by OFAC; and (iv) neither you or any affiliate person
|
||||
or entity deals in, or otherwise engages in any transaction relating to any property or interests in
|
||||
property blocked pursuant to the Executive Order.
|
||||
</li>
|
||||
|
||||
<li>With certain limited exceptions, in the following January the Zcash Foundation will report the value
|
||||
of the funds as taxable income on either US tax form 1099-MISC (for US taxpayers) or 1042-S (for foreign
|
||||
persons). These forms will report the value of the award in USD at the date it was distributed. You may need to
|
||||
include this income when filing your taxes, and it may affect your total tax due and estimated tax
|
||||
payments. Here are more details on <a href={'https://www.irs.gov/forms-pubs/about-form-1099-misc'}>filing the
|
||||
1099-MISC</a> in the US, and its tax implications.
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Your funds will be disbursed in a shielded Zcash cryptocurrency (ZEC), then it will be via an
|
||||
on-blockchain
|
||||
fund transfer transaction. The Foundation will use this third-party service and market for converting ZEC
|
||||
to
|
||||
other currencies are listed here based on the price of the agreed-upon date close of day at :
|
||||
<a href={'https://messari.io/asset/zcash'}>https://messari.io/asset/zcash</a>. For all grants, the
|
||||
agreed-upon date will be the date that the grant was
|
||||
approved, as noted in the grant platform. Note that the Zcash Foundation understands the regulatory and
|
||||
compliance risks associated with transacting in cryptocurrencies.
|
||||
</li>
|
||||
|
||||
<li>Tax Implications: Please be aware that in some countries, taxes will be due on the ZEC grant you receive
|
||||
(for the receipt of ZEC, when you sell/exchange it, or both). Specifically:
|
||||
|
||||
<ol>
|
||||
<li>Capital gain tax may be due if you later sell/exchange your ZEC for a higher price</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ol>
|
||||
</Modal>
|
||||
|
||||
<Form.Item
|
||||
label="Title"
|
||||
label='Title'
|
||||
validateStatus={errors.title ? 'error' : undefined}
|
||||
help={errors.title}
|
||||
>
|
||||
<Input
|
||||
size="large"
|
||||
name="title"
|
||||
placeholder="Short and sweet"
|
||||
type="text"
|
||||
size='large'
|
||||
name='title'
|
||||
placeholder='Short and sweet'
|
||||
type='text'
|
||||
value={title}
|
||||
onChange={this.handleInputChange}
|
||||
maxLength={200}
|
||||
|
@ -140,13 +228,13 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="Brief"
|
||||
label='Brief'
|
||||
validateStatus={errors.brief ? 'error' : undefined}
|
||||
help={errors.brief}
|
||||
>
|
||||
<Input.TextArea
|
||||
name="brief"
|
||||
placeholder="A one-liner elevator-pitch version of your proposal, max 140 chars."
|
||||
name='brief'
|
||||
placeholder='A one-liner elevator-pitch version of your proposal, max 140 chars.'
|
||||
value={brief}
|
||||
onChange={this.handleInputChange}
|
||||
rows={3}
|
||||
|
@ -155,7 +243,7 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
</Form.Item>
|
||||
|
||||
<Form.Item
|
||||
label="Target amount"
|
||||
label='Target amount'
|
||||
validateStatus={errors.target ? 'error' : undefined}
|
||||
help={
|
||||
errors.target ||
|
||||
|
@ -163,13 +251,13 @@ class CreateFlowBasics extends React.Component<Props, State> {
|
|||
}
|
||||
>
|
||||
<Input
|
||||
size="large"
|
||||
name="target"
|
||||
placeholder="1.5"
|
||||
type="number"
|
||||
size='large'
|
||||
name='target'
|
||||
placeholder='1.5'
|
||||
type='number'
|
||||
value={target}
|
||||
onChange={this.handleInputChange}
|
||||
addonBefore="$"
|
||||
addonBefore='$'
|
||||
maxLength={16}
|
||||
/>
|
||||
</Form.Item>
|
||||
|
|
|
@ -83,8 +83,8 @@ export function getCreateErrors(
|
|||
}
|
||||
|
||||
// RFP opt-in
|
||||
if (rfpOptIn === null) {
|
||||
errors.rfpOptIn = 'Please accept or decline KYC';
|
||||
if (!rfpOptIn) {
|
||||
errors.rfpOptIn = 'Please accept KYC to submit.'
|
||||
}
|
||||
|
||||
// Title
|
||||
|
|
Loading…
Reference in New Issue