add form validators and html form to add contributors

This commit is contained in:
Jonathan Rainville 2019-04-09 14:23:36 -04:00
parent 9b61c3da45
commit 58637423d1
No known key found for this signature in database
GPG Key ID: 5F4630B759727D9C
5 changed files with 129 additions and 3 deletions

View File

@ -1,12 +1,50 @@
/*global web3*/
import React from 'react';
import {Button, Form} from 'react-bootstrap';
import ValidatedForm from 'react-validation/build/form';
import Input from 'react-validation/build/input';
import {required, isAddress} from '../validators';
class Admin extends React.Component {
state = {
contributorName: '',
contributorAddress: ''
};
onChange = (name, e) => {
this.setState({[name]: e.target.value});
};
addContributor = (e) => {
e.preventDefault();
console.log('Submit', this.state);
};
render() {
const {contributorAddress, contributorName} = this.state;
return (<div>
<h3>Admin Panel</h3>
<h2>Admin Panel</h2>
<h3>Add a contributor</h3>
<ValidatedForm onSubmit={(e) => this.addContributor(e)}>
<Form.Group controlId="formContributor">
<Form.Label>Contributor name</Form.Label>
<Input type="text" placeholder="Name" value={contributorName}
onChange={(e) => this.onChange('contributorName', e)}
className="form-control"
validations={[required]}/>
</Form.Group>
<Form.Group controlId="formAddress">
<Form.Label>Contributor address</Form.Label>
<Input type="text" placeholder="0x" value={contributorAddress}
onChange={(e) => this.onChange('contributorAddress', e)}
className="form-control"
validations={[required, isAddress]}/>
</Form.Group>
<Button variant="primary" onClick={(e) => this.addContributor(e)}>Add</Button>
</ValidatedForm>
</div>);
}
}

View File

@ -2,7 +2,7 @@ import React from 'react'
import {Navbar, Nav} from 'react-bootstrap';
const Header = () => (<Navbar bg="light" expand="lg">
<Navbar.Brand href="/#/">Meritocracy</Navbar.Brand>
<Navbar.Brand href="/#/">Status Meritocracy</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav"/>
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">

60
app/js/validators.js Normal file
View File

@ -0,0 +1,60 @@
/*global Web3*/
import React from 'react';
import {Form} from 'react-bootstrap';
export const required = (value) => {
if (!value.toString().trim().length) {
return <Form.Control.Feedback type="invalid" className="d-block">This field is required</Form.Control.Feedback>;
}
};
export const isInteger = (value) => {
value = parseFloat(value);
if (!Number.isInteger(value)) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be an integer</Form.Control.Feedback>;
}
};
export const isNumber = (value) => {
if (Number.isNaN(value)) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be an number</Form.Control.Feedback>;
}
};
export const lowerThan = (max, value) => {
if (value >= max) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be lower than {max}</Form.Control.Feedback>;
}
};
export const lowerEqThan = (max, value) => {
if (value > max) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be lower or equal than {max}</Form.Control.Feedback>;
}
};
export const higherThan = (min, value) => {
if (value <= min) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be higher than {min}</Form.Control.Feedback>;
}
};
export const higherEqThan = (min, value) => {
if (value < min) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be higher or equal than {min}</Form.Control.Feedback>;
}
};
export const isAddress = (value) => {
if (!Web3.utils.isAddress(value)) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be a valid Ethereum address</Form.Control.Feedback>;
}
};
export const isJSON = (value) => {
try {
JSON.parse(value);
} catch (e) {
return <Form.Control.Feedback type="invalid" className="d-block">This field needs to be a valid JSON string</Form.Control.Feedback>;
}
};

27
package-lock.json generated
View File

@ -507,6 +507,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
},
"lodash.omit": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
},
"loose-envify": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
@ -827,6 +832,18 @@
"react-lifecycles-compat": "^3.0.4"
}
},
"react-validation": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/react-validation/-/react-validation-3.0.7.tgz",
"integrity": "sha1-tQcL+KbnN7hw2Hu/tyzMpys/N1A=",
"requires": {
"lodash.omit": "^4.5.0",
"prop-types": "^15.6.0",
"react": "^16.0.0",
"shallow-equal": "^1.0.0",
"uuid": "^3.1.0"
}
},
"rechoir": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
@ -882,6 +899,11 @@
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"shallow-equal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallow-equal/-/shallow-equal-1.1.0.tgz",
"integrity": "sha512-0SW1nWo1hnabO62SEeHsl8nmTVVEzguVWZCj5gaQrgWAxz/BaCja4OWdJBWLVPDxdtE/WU7c98uUCCXyPHSCvw=="
},
"shelljs": {
"version": "0.8.3",
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz",
@ -943,6 +965,11 @@
"invariant": "^2.2.4"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
},
"warning": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",

View File

@ -17,6 +17,7 @@
"react-bootstrap": "1.0.0-beta.6",
"react-dom": "^16.8.6",
"react-numeric-input": "^2.2.3",
"react-select": "^2.3.0"
"react-select": "^2.3.0",
"react-validation": "^3.0.7"
}
}