diff --git a/packages/concordia-app/package.json b/packages/concordia-app/package.json index 65c1b25..0e039b8 100644 --- a/packages/concordia-app/package.json +++ b/packages/concordia-app/package.json @@ -9,7 +9,7 @@ "eject": "react-scripts eject", "postinstall": "patch-package", "analyze": "source-map-explorer 'build/static/js/*.js'", - "lint": "yarn run eslint . --format table" + "lint": "yarn run eslint --ext js,jsx . --format table" }, "browserslist": { "production": [ diff --git a/packages/concordia-app/src/components/App.jsx b/packages/concordia-app/src/components/App.jsx index 4086e07..88704c8 100644 --- a/packages/concordia-app/src/components/App.jsx +++ b/packages/concordia-app/src/components/App.jsx @@ -1,34 +1,33 @@ -import React from 'react' -import { Provider } from 'react-redux' -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom' -import LoadingContainer from './LoadingContainer' -import PropTypes from 'prop-types' +import React from 'react'; +import { Provider } from 'react-redux'; +import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; +import PropTypes from 'prop-types'; +import LoadingContainer from './LoadingContainer'; // CSS import '../assets/css/app.css'; import CoreLayoutContainer from './CoreLayoutContainer'; import HomeContainer from './HomeContainer'; -import NotFound from '../components/NotFound'; - +import NotFound from './NotFound'; const App = ({ store }) => ( - - - - - - - - + + + + + + + + -) +); App.propTypes = { - store: PropTypes.object.isRequired -} + store: PropTypes.object.isRequired, +}; -export default App +export default App; diff --git a/packages/concordia-app/src/components/AppContext.js b/packages/concordia-app/src/components/AppContext.js deleted file mode 100644 index 5534716..0000000 --- a/packages/concordia-app/src/components/AppContext.js +++ /dev/null @@ -1,72 +0,0 @@ -// Modified version of https://github.com/trufflesuite/drizzle/blob/develop/packages/react-plugin/src/DrizzleContext.js -import React from "react"; - -const Context = React.createContext(); - -class Provider extends React.Component { - state = { - drizzleState: null, - drizzleInitialized: false, - breezeState: null, - breezeInitialized: false - }; - - componentDidMount() { - const { drizzle, breeze } = this.props; - // subscribe to changes in the store, keep state up-to-date - this.unsubscribe = drizzle.store.subscribe(() => { - const drizzleState = drizzle.store.getState(); - const breezeState = breeze.store.getState(); - - if (drizzleState.drizzleStatus.initialized) { - this.setState({ - drizzleState, - drizzleInitialized: true - }); - } - if (breezeState.breezeStatus.initialized) { - this.setState({ - breezeState: breezeState, - breezeInitialized: true - }); - } - }); - - this.unsubscribe = breeze.store.subscribe(() => { - const breezeState = breeze.store.getState(); - if (breezeState.breezeStatus.initialized) { - this.setState({ - breezeState: breezeState, - breezeInitialized: true - }); - } - }); - } - - componentWillUnmount() { - this.unsubscribe(); - } - - render() { - return ( - - {this.props.children} - - ); - } -} - -export default { - Context: Context, - Consumer: Context.Consumer, - Provider -}; diff --git a/packages/concordia-app/src/components/AppContext.jsx b/packages/concordia-app/src/components/AppContext.jsx new file mode 100644 index 0000000..6b8b739 --- /dev/null +++ b/packages/concordia-app/src/components/AppContext.jsx @@ -0,0 +1,81 @@ +// Modified version of https://github.com/trufflesuite/drizzle/blob/develop/packages/react-plugin/src/DrizzleContext.js +import React from 'react'; + +const Context = React.createContext(); + +class Provider extends React.Component { + constructor(props) { + super(props); + + this.state = { + drizzleState: null, + drizzleInitialized: false, + breezeState: null, + breezeInitialized: false, + }; + } + + componentDidMount() { + const { drizzle, breeze } = this.props; + // subscribe to changes in the store, keep state up-to-date + this.unsubscribe = drizzle.store.subscribe(() => { + const drizzleState = drizzle.store.getState(); + const breezeState = breeze.store.getState(); + + if (drizzleState.drizzleStatus.initialized) { + this.setState({ + drizzleState, + drizzleInitialized: true, + }); + } + if (breezeState.breezeStatus.initialized) { + this.setState({ + breezeState, + breezeInitialized: true, + }); + } + }); + + this.unsubscribe = breeze.store.subscribe(() => { + const breezeState = breeze.store.getState(); + if (breezeState.breezeStatus.initialized) { + this.setState({ + breezeState, + breezeInitialized: true, + }); + } + }); + } + + componentWillUnmount() { + this.unsubscribe(); + } + + render() { + const { + drizzleState, drizzleInitialized, breezeState, breezeInitialized, + } = this.state; + const { drizzle, breeze, children } = this.props; + + return ( + + {children} + + ); + } +} + +export default { + Context, + Consumer: Context.Consumer, + Provider, +}; diff --git a/packages/concordia-app/src/components/CoreLayoutContainer.jsx b/packages/concordia-app/src/components/CoreLayoutContainer.jsx index 4a72130..5da971e 100644 --- a/packages/concordia-app/src/components/CoreLayoutContainer.jsx +++ b/packages/concordia-app/src/components/CoreLayoutContainer.jsx @@ -1,19 +1,21 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import MenuComponent from './MenuComponent'; -export default class CoreLayout extends Component { - render() { - return ( -
- - {this.props.children} -
- ) - } -} +const CoreLayout = (props) => { + const { children } = props; + + return ( +
+ + {children} +
+ ); +}; CoreLayout.propTypes = { - children: PropTypes.element.isRequired + children: PropTypes.element.isRequired, }; + +export default CoreLayout; diff --git a/packages/concordia-app/src/components/HomeContainer.jsx b/packages/concordia-app/src/components/HomeContainer.jsx index 6fdafbb..d11b3f4 100644 --- a/packages/concordia-app/src/components/HomeContainer.jsx +++ b/packages/concordia-app/src/components/HomeContainer.jsx @@ -1,9 +1,5 @@ -import React, { Component } from 'react'; +import React from 'react'; -class HomeContainer extends Component { - render() { - return(

TODO: Home Container

); - } -} +const HomeContainer = () => (

TODO: Home Container

); export default HomeContainer; diff --git a/packages/concordia-app/src/components/LoadingComponent.jsx b/packages/concordia-app/src/components/LoadingComponent.jsx index 6f4ab70..7472b65 100644 --- a/packages/concordia-app/src/components/LoadingComponent.jsx +++ b/packages/concordia-app/src/components/LoadingComponent.jsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import { Container, Progress } from 'semantic-ui-react'; @@ -7,67 +7,61 @@ import { Container, Progress } from 'semantic-ui-react'; import '../assets/css/loading-component.css'; // Images -import ethereum_logo from '../assets/images/ethereum_logo.svg'; -import ipfs_logo from '../assets/images/ipfs_logo.svg'; -import orbitdb_logo from '../assets/images/orbitdb_logo.png'; -import app_logo from '../assets/images/app_logo.png'; +import ethereumLogo from '../assets/images/ethereum_logo.svg'; +import ipfsLogo from '../assets/images/ipfs_logo.svg'; +import orbitdbLogo from '../assets/images/orbitdb_logo.png'; +import appLogo from '../assets/images/app_logo.png'; -class LoadingComponent extends Component { - render(){ - const { image_type, message_list, progress_type } = this.props ; - let imageSrc, imageAlt, listItems, indicating, error; +const LoadingComponent = (props) => { + const { + imageType, messageList, progressType, title, message, progress, + } = props; + let imageSrc; let imageAlt; let listItems; let indicating; let + error; - if (image_type === "ethereum"){ - imageSrc = ethereum_logo; - imageAlt = "ethereum_logo"; - } - else if (image_type === "ipfs"){ - imageSrc = ipfs_logo; - imageAlt = "ipfs_logo"; - } - else if (image_type === "orbit"){ - imageSrc = orbitdb_logo; - imageAlt = "orbitdb_logo"; - } - else if (image_type === "app"){ - imageSrc = app_logo; - imageAlt = "app_logo"; - } + if (imageType === 'ethereum') { + imageSrc = ethereumLogo; + imageAlt = 'ethereum_logo'; + } else if (imageType === 'ipfs') { + imageSrc = ipfsLogo; + imageAlt = 'ipfs_logo'; + } else if (imageType === 'orbit') { + imageSrc = orbitdbLogo; + imageAlt = 'orbitdb_logo'; + } else if (imageType === 'app') { + imageSrc = appLogo; + imageAlt = 'app_logo'; + } - if(progress_type === "indicating") - indicating = true; - else if(progress_type === "error") - error = true; + if (progressType === 'indicating') indicating = true; + else if (progressType === 'error') error = true; - if(message_list){ - listItems = message_list.map((listItem) => -
  • {listItem}
  • - ); - } + if (messageList) { + listItems = messageList.map((listItem) =>
  • {listItem}
  • ); + } - const list = message_list ? : ''; + const list = messageList ? : ''; - return( -
    - - {imageAlt} -

    {this.props.title}

    -

    {this.props.message}

    - {list} -
    - -
    - ); - } -} + return ( +
    + + {imageAlt} +

    {title}

    +

    {message}

    + {list} +
    + +
    + ); +}; LoadingComponent.propTypes = { - title: PropTypes.string.isRequired, - message: PropTypes.string.isRequired, - message_list: PropTypes.arrayOf(PropTypes.string), - image_type: PropTypes.string.isRequired, - progress: PropTypes.number.isRequired, - progress_type: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + message: PropTypes.string.isRequired, + messageList: PropTypes.arrayOf(PropTypes.string), + imageType: PropTypes.string.isRequired, + progress: PropTypes.number.isRequired, + progressType: PropTypes.string.isRequired, }; export default LoadingComponent; diff --git a/packages/concordia-app/src/components/LoadingContainer.jsx b/packages/concordia-app/src/components/LoadingContainer.jsx index c8ed6e0..0260132 100644 --- a/packages/concordia-app/src/components/LoadingContainer.jsx +++ b/packages/concordia-app/src/components/LoadingContainer.jsx @@ -1,7 +1,7 @@ import React, { Children, Component } from 'react'; import { connect } from 'react-redux'; -import { breezeConstants } from '@ezerous/breeze' +import { breezeConstants } from '@ezerous/breeze'; import LoadingComponent from './LoadingComponent'; @@ -9,128 +9,159 @@ import LoadingComponent from './LoadingComponent'; import '../assets/css/loading-component.css'; class LoadingContainer extends Component { - render() { - if ((this.props.web3.status === 'initializing' || !this.props.web3.networkId) - && !this.props.web3.networkFailed) { - return - } - - if (this.props.web3.status === 'failed' || this.props.web3.networkFailed) { - return - } - - if (this.props.web3.status === 'initialized' && this.props.web3.accountsFailed) { - return - } - - if (this.props.drizzleStatus.initializing - || (!this.props.drizzleStatus.failed && !this.props.contractInitialized && this.props.contractDeployed )){ - return - } - - if (!this.props.contractDeployed) { - return - } - - if (this.props.ipfsStatus === breezeConstants.STATUS_INITIALIZING) { - return - } - - if (this.props.ipfsStatus === breezeConstants.STATUS_FAILED) { - return - } - - if (this.props.orbitStatus === breezeConstants.STATUS_INITIALIZING) { - const message = process.env.NODE_ENV === 'development' - ? 'If needed, please sign the transaction in MetaMask to create the databases.' - : 'Please sign the transaction in MetaMask to create the databases.'; - return - } - - if (this.props.orbitStatus === breezeConstants.STATUS_FAILED) { - return - } - - if (!this.props.userFetched){ - return - } - - return Children.only(this.props.children); + render() { + const { + web3: { + status, networkId, networkFailed, accountsFailed, + }, + drizzleStatus: { + initializing, + failed, + }, + contractInitialized, contractDeployed, ipfsStatus, orbitStatus, userFetched, children, + } = this.props; + + if ((status === 'initializing' || !networkId) + && !networkFailed) { + return ( + + ); } + + if (status === 'failed' || networkFailed) { + return ( + + ); + } + + if (status === 'initialized' && accountsFailed) { + return ( + + ); + } + + if (initializing + || (!failed && !contractInitialized && contractDeployed)) { + return ( + + ); + } + + if (!contractDeployed) { + return ( + + ); + } + + if (ipfsStatus === breezeConstants.STATUS_INITIALIZING) { + return ( + + ); + } + + if (ipfsStatus === breezeConstants.STATUS_FAILED) { + return ( + + ); + } + + if (orbitStatus === breezeConstants.STATUS_INITIALIZING) { + const message = process.env.NODE_ENV === 'development' + ? 'If needed, please sign the transaction in MetaMask to create the databases.' + : 'Please sign the transaction in MetaMask to create the databases.'; + return ( + + ); + } + + if (orbitStatus === breezeConstants.STATUS_FAILED) { + return ( + + ); + } + + if (!userFetched) { + return ( + + ); + } + + return Children.only(children); + } } const mapStateToProps = (state) => ({ - drizzleStatus: state.drizzleStatus, - breezeStatus: state.breezeStatus, - ipfsStatus: state.ipfs.status, - orbitStatus: state.orbit.status, - web3: state.web3, - accounts: state.accounts, - contractInitialized: state.contracts.Forum.initialized, - contractDeployed: state.contracts.Forum.deployed, - userFetched: state.user.address + drizzleStatus: state.drizzleStatus, + breezeStatus: state.breezeStatus, + ipfsStatus: state.ipfs.status, + orbitStatus: state.orbit.status, + web3: state.web3, + accounts: state.accounts, + contractInitialized: state.contracts.Forum.initialized, + contractDeployed: state.contracts.Forum.deployed, + userFetched: state.user.address, }); export default connect(mapStateToProps)(LoadingContainer); diff --git a/packages/concordia-app/src/components/MenuComponent.jsx b/packages/concordia-app/src/components/MenuComponent.jsx index c71b040..e0c2421 100644 --- a/packages/concordia-app/src/components/MenuComponent.jsx +++ b/packages/concordia-app/src/components/MenuComponent.jsx @@ -1,38 +1,35 @@ -import React, { Component } from 'react'; -import { withRouter } from "react-router"; +import React from 'react'; +import { withRouter } from 'react-router'; import { Menu } from 'semantic-ui-react'; -import AppContext from "./AppContext"; +import AppContext from './AppContext'; -import app_logo from '../assets/images/app_logo.png'; +import appLogo from '../assets/images/app_logo.png'; import SignUpForm from './SignUpForm'; -class MenuComponent extends Component { - render() { - return ( - - {context => { - return( -
    - - { this.props.history.push("/"); }} - > - app_logo - +const MenuComponent = (props) => { + const { history: { push } } = props; - + return ( + + {() => ( +
    + + { push('/'); }} + > + app_logo + - -
    - ) - } - } -
    - ) - } -} + + +
    +
    + )} +
    + ); +}; export default withRouter(MenuComponent); diff --git a/packages/concordia-app/src/components/NotFound.jsx b/packages/concordia-app/src/components/NotFound.jsx index c73a7e5..9b5be95 100644 --- a/packages/concordia-app/src/components/NotFound.jsx +++ b/packages/concordia-app/src/components/NotFound.jsx @@ -3,7 +3,7 @@ import pageNotFound from '../assets/images/PageNotFound.jpg'; const NotFound = () => (
    Page not found! diff --git a/packages/concordia-app/src/components/SignUpForm.jsx b/packages/concordia-app/src/components/SignUpForm.jsx index fad79bc..3c9fed3 100644 --- a/packages/concordia-app/src/components/SignUpForm.jsx +++ b/packages/concordia-app/src/components/SignUpForm.jsx @@ -1,139 +1,144 @@ import React, { Component } from 'react'; -import { Button, Form, Menu, Message, Modal } from 'semantic-ui-react'; +import { + Button, Form, Menu, Message, Modal, +} from 'semantic-ui-react'; -import AppContext from "./AppContext"; import { connect } from 'react-redux'; +import AppContext from './AppContext'; const contractName = 'Forum'; const checkUsernameTakenMethod = 'isUserNameTaken'; const signUpMethod = 'signUp'; class SignUpForm extends Component { - constructor(props, context) { - super(props, context); - - // For quick access - this.contract = this.context.drizzle.contracts[contractName]; - - this.handleInputChange = this.handleInputChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.completeAction = this.completeAction.bind(this); - - this.checkedUsernames = []; - - this.state = { - usernameInput: '', - error: false, - errorHeader: '', - errorMessage: '', - signingUp: false, - }; + constructor(props, context) { + super(props, context); + + // For quick access + this.contract = this.context.drizzle.contracts[contractName]; + + this.handleInputChange = this.handleInputChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + this.completeAction = this.completeAction.bind(this); + + this.checkedUsernames = []; + + this.state = { + usernameInput: '', + error: false, + errorHeader: '', + errorMessage: '', + signingUp: false, + }; + } + + componentDidUpdate() { + // TODO + } + + handleSubmit() { + const { usernameInput, error } = this.state; + + if (usernameInput === '') { + this.setState({ + error: true, + errorHeader: 'Data Incomplete', + errorMessage: 'You need to provide a username', + }); + } else if (!error) { + // TODO + // // Makes sure current input username has been checked for availability + // if (this.checkedUsernames.some((e) => e.usernameChecked === usernameInput)) { + // this.completeAction(); + // } + this.completeAction(); } - - handleInputChange(e, { name, value }) { - this.setState({ - [name]: value, - error: false, - }); - if (value !== '') { - if (this.checkedUsernames.length > 0) { - if (this.checkedUsernames.some((e) => e.usernameChecked === value)) { - return; - } - } - - this.contract.methods[checkUsernameTakenMethod].cacheCall( - value, - ); - } - } - - handleSubmit() { - const { usernameInput, error } = this.state; - - if (usernameInput === '') { - this.setState({ - error: true, - errorHeader: 'Data Incomplete', - errorMessage: 'You need to provide a username', - }); - } else if (!error) { - // TODO - // // Makes sure current input username has been checked for availability - // if (this.checkedUsernames.some((e) => e.usernameChecked === usernameInput)) { - // this.completeAction(); - // } - this.completeAction(); + } + + handleInputChange(e, { name, value }) { + this.setState({ + [name]: value, + error: false, + }); + if (value !== '') { + if (this.checkedUsernames.length > 0) { + if (this.checkedUsernames.some((e) => e.usernameChecked === value)) { + return; } - } + } - componentDidUpdate() { - // TODO + this.contract.methods[checkUsernameTakenMethod].cacheCall( + value, + ); } - - completeAction() { - const { usernameInput } = this.state; - const { user, account } = this.props; - - if (user.hasSignedUp) { - console.log('Signing up..') - this.contract.methods['signUp'].cacheSend(usernameInput); - } else { - this.setState({ - signingUp: true, - }); - this.contract.methods[signUpMethod].cacheSend( - ...[usernameInput], { from: account }, - ); - } - this.setState({ - usernameInput: '', - }); + } + + completeAction() { + const { usernameInput } = this.state; + const { user, account } = this.props; + + if (user.hasSignedUp) { + console.log('Signing up..'); + this.contract.methods.signUp.cacheSend(usernameInput); + } else { + this.setState({ + signingUp: true, + }); + this.contract.methods[signUpMethod].cacheSend( + ...[usernameInput], { from: account }, + ); } - - render() { - const { - error, usernameInput, errorHeader, errorMessage, signingUp, - } = this.state; - - return( - this.handleSubmit(e)} trigger={ - - }> - Sign Up - - - - - - - this.handleSubmit(e)} + trigger={( + + )} + > + Sign Up + + + + + -