176 lines
5.5 KiB
JavaScript
Raw Permalink Normal View History

2018-06-25 13:09:10 +10:00
import { Button, FormGroup, ControlLabel, FormControl, HelpBlock, Image, Grid, Col, Row, PageHeader } from 'react-bootstrap';
import { withRouter } from 'react-router-dom'
import React, { Component } from 'react';
import FieldGroup from './FieldGroup';
class UpdateUser extends Component {
//#region Constructor
constructor(props, context) {
super(props, context);
// initial state
this.state = {
isLoading: false,
picture: '',
description: this.props.user.description,
error: '',
formState: null,
formUpdated: false
};
}
//#endregion
//#region Component events
/**
* Handles the 'Update user' button click event which
* sends a transaction to the contract to update the
* user's profile.
*
* @returns {null}
*/
_handleClick = async () => {
// if the form has not been updated, do nothing
if (!this.state.formUpdated) return;
// show loading state
this.setState({ isLoading: true });
// if the user has updated their photo, try to upload it to ipfs
// and use the resulting ipfs hash to send to the contract as part
// of the user's profile.
let hash = '';
if (this.state.picture !== '') {
try {
// upload the file to ipfs and get the resulting hash
hash = '';
}
catch (err) {
// stop loading state and show user the error
return this.setState({ isLoading: false, formState: 'error', error: err.message });
}
}
const { account, user } = this.props;
const { description } = this.state;
// get a handle for the editAccount method
// get a gas estimate for the transaction with the input username
// and description
try {
// send the transaction with our gas estimate (plus a little bit more in case the contract)
// state has changed since we got our estimate
// if (result.status && !Boolean(result.status.toString().replace('0x', ''))) {
// return this.setState({ isLoading: false, formState: 'error', formUpdated: false, error: 'Error executing transaction, transaction details: ' + JSON.stringify(result) });
// }
// stop loading state, and render the form as successful
this.setState({ isLoading: false, formState: 'success', formUpdated: false });
// tell parent we've updated our user, so the current
// user is re-fetched to get the user's details
return this.props.onAfterUserUpdate();
}
catch (err) {
// stop loading state and show user the error
this.setState({ isLoading: false, formState: 'error', formUpdated: false, error: err.message });
}
return null;
}
/**
* When user changes an input value, record that in the state.
* Additionally, sets state that the form has been updated to
* allow for more fine validation control
*
* @param {SyntheticEvent} cross-browser wrapper around the browsers native event
*
* @return {null}
*/
_handleChange(e) {
let state = { formUpdated: true };
const input = e.target.name;
const value = e.target.value;
state[input] = value;
this.setState(state);
}
//#endergion
//#region React lifecycle events
componentDidUpdate(prevProps){
if(this.props.user.description !== prevProps.user.description){
this.setState({description: this.props.user.description});
}
}
render() {
const { isLoading, error, formState, formUpdated, description, picture } = this.state;
const { user } = this.props;
const feedback = formState === 'success' ? 'Saved' : error;
return (
<Grid>
<Row>
<Col xs={12}>
<PageHeader>Update { user.username } <small>{this.props.account}</small></PageHeader>
</Col>
</Row>
<Row>
<Col xs={12}>
<form onSubmit={ isLoading || !formUpdated ? null : (e) => this._handleClick(e) }>
<FieldGroup
type="text"
value={ user.username }
disabled={true}
name="username"
label="Username"
/>
<FieldGroup
type="text"
value={ description }
placeholder="description"
onChange={ (e) => this._handleChange(e) }
name="description"
label="Description"
validationState={ formState }
/>
<FieldGroup
type="file"
value={ picture }
onChange={ (e) => this._handleChange(e) }
name="picture"
label="Profile picture"
inputRef={ (input) => this.inputPicture = input }
validationState={ formState }
/>
<FormGroup>
{ user.picture.length ? <Image src={ user.picture } width="100" circle /> : '' }
</FormGroup>
<FormGroup>
<Button
bsStyle="primary"
disabled={ isLoading || !formUpdated }
onClick={ isLoading || !formUpdated ? null : (e) => this._handleClick(e) }
>
{ isLoading ? 'Loading...' : 'Update profile' }
</Button>
</FormGroup>
<FormGroup
validationState={ formState }
>
<HelpBlock>{ feedback }</HelpBlock>
</FormGroup>
</form>
</Col>
</Row>
</Grid>
);
}
//#endregion
}
export default withRouter(UpdateUser);